[blog 項目實戰派]csharp通過dll調用opencv函數,圖片作為參數
一直想做着方面的研究,但是因為這個方面的知識過於小眾,也是由於自己找資料的能力比較弱,知道今天才找到了比較好的資料。一個是thinimage,一個是basework,里面都實現了這里的“csharp通過dll調用opencv函數,並且采用圖片作為參數”。這里小結如下。
關於如何“
csharp通過dll調用opencv函數
”,請參考前面博文,這里主要說如何“采用圖片為參數”。
在編寫圖像識別/增強/機器視覺等項目的時候,一般會將算法打包成dll文件給客戶,如果界面是用mfc寫的話,是很好實現這個功能的。但是也有一些時候,由於特殊的需求,或者為了更快地實現更為豐富的界面效果,選擇csharp作為界面。這個時候就需要“圖片作為參數”。
本項目是一個實驗項目,功能就是csharp下讀入一個24位彩色圖片,調用opencv進行ycbcr變換后,然后再csharp上面顯示出來。
因為在調用的過程中,傳遞的只是指針,
所以
這個轉換需要做兩方面的工作。
一個方面是 csharp這邊的,具體來說就是需要創建bitmap的結構,並且在調用的過程中鎖定內存;一個方面是在opencv和dll編寫這邊的,要能夠讀入內存區域,並且翻譯成mat結構。然后在這個基礎上面編寫相關的處理程序。
繼續開源項目ThinyImage,這個過程的以實現。
ThinyImage本身就是csharp調用c++編寫的dll實現的圖像處理軟件,也實現了一些功能:

那么在現有的程序上面添加GO算法接口

csharp這邊,進行內存鎖定和函數調用操作
private
void ToolStripMenuItem_Click(object sender, EventArgs e)
{
StartImageProcess();
try
{
BitmapData bitmapData = m_bitmap.LockBits( new Rectangle( 0, 0, m_bitmap.Width, m_bitmap.Height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
NativeMethods.DirectCopy(bitmapData.Scan0, bitmapData.Width, bitmapData.Height, bitmapData.Stride, m_bpp);
m_bitmap.UnlockBits(bitmapData);
}
catch (System.Exception)
{
}
EndImageProcess();
}
{
StartImageProcess();
try
{
BitmapData bitmapData = m_bitmap.LockBits( new Rectangle( 0, 0, m_bitmap.Width, m_bitmap.Height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
NativeMethods.DirectCopy(bitmapData.Scan0, bitmapData.Width, bitmapData.Height, bitmapData.Stride, m_bpp);
m_bitmap.UnlockBits(bitmapData);
}
catch (System.Exception)
{
}
EndImageProcess();
}
相應添加程序接口,
//聯合opencv的模板函數
void DirectCopy(TiBitmapData & bitmap){
//獲得基本參數
int width = bitmap.GetWidth();
int height = bitmap.GetHeight();
int stride = bitmap.GetStride();
int bpp = bitmap.GetBpp();
u8 * bmpData = bitmap.GetBmpData();
int offset = stride - width * bpp;
Mat src = Mat : :zeros(width,height,CV_8UC3);
//將bitmap的內容拷貝到src中
for( int i = 0;i <src.rows;i ++){
for( int j = 0;j <src.cols;j ++){
src.at <Vec3b >(i,j)[ 0] =( int)bmpData[TiBlue];
src.at <Vec3b >(i,j)[ 1] =( int)bmpData[TiGreen];
src.at <Vec3b >(i,j)[ 2] =( int)bmpData[TiRed];
bmpData += bpp;
}
bmpData += offset;
}
/////OPENCV具體操作過程////////////////////////
Mat dst;
cvtColor(src,dst,COLOR_BGR2YCrCb);;
/////OPENCV過程結束////////////////////////
bmpData = bitmap.GetBmpData();
for( int i = 0;i <src.rows;i ++){
for( int j = 0;j <src.cols;j ++){
bmpData[TiBlue] = dst.at <Vec3b >(i,j)[ 0];
bmpData[TiGreen] = dst.at <Vec3b >(i,j)[ 1];
bmpData[TiRed] = dst.at <Vec3b >(i,j)[ 2];
bmpData += bpp;
}
bmpData += offset;
}
}
}
void DirectCopy(TiBitmapData & bitmap){
//獲得基本參數
int width = bitmap.GetWidth();
int height = bitmap.GetHeight();
int stride = bitmap.GetStride();
int bpp = bitmap.GetBpp();
u8 * bmpData = bitmap.GetBmpData();
int offset = stride - width * bpp;
Mat src = Mat : :zeros(width,height,CV_8UC3);
//將bitmap的內容拷貝到src中
for( int i = 0;i <src.rows;i ++){
for( int j = 0;j <src.cols;j ++){
src.at <Vec3b >(i,j)[ 0] =( int)bmpData[TiBlue];
src.at <Vec3b >(i,j)[ 1] =( int)bmpData[TiGreen];
src.at <Vec3b >(i,j)[ 2] =( int)bmpData[TiRed];
bmpData += bpp;
}
bmpData += offset;
}
/////OPENCV具體操作過程////////////////////////
Mat dst;
cvtColor(src,dst,COLOR_BGR2YCrCb);;
/////OPENCV過程結束////////////////////////
bmpData = bitmap.GetBmpData();
for( int i = 0;i <src.rows;i ++){
for( int j = 0;j <src.cols;j ++){
bmpData[TiBlue] = dst.at <Vec3b >(i,j)[ 0];
bmpData[TiGreen] = dst.at <Vec3b >(i,j)[ 1];
bmpData[TiRed] = dst.at <Vec3b >(i,j)[ 2];
bmpData += bpp;
}
bmpData += offset;
}
}
}
完成相應的功能
