如何在C#中使用OpenCV(GOCW使用教程)
1、什么是GOCW
為了解決在Csharp下編寫(xiě)OpenCV程序的問(wèn)題,我做過(guò)比較深入的研究,并且實(shí)現(xiàn)了高效可用的方法GreenOpenCsharpWrapper(GOCW)。通過(guò)這種方法,能夠分離界面和算法業(yè)務(wù),高效率完成算法調(diào)用,而且非常方便進(jìn)行算法維護(hù)。應(yīng)該說(shuō)是我在多年項(xiàng)目實(shí)踐中不斷總結(jié)提煉出來(lái)的一點(diǎn)東西。
GOCW的發(fā)布地址為:https://gitee.com/jsxyhelu2020/gocw
2、GOCW有什么特點(diǎn)
分離界面和算法業(yè)務(wù)
圖像數(shù)據(jù)直接通過(guò)內(nèi)存?zhèn)髦?,高效率完成算法調(diào)用
直接編寫(xiě)C++語(yǔ)法程序,方便維護(hù)改進(jìn)
在C#中可以通過(guò)CLR方式引用,提供函數(shù)級(jí)別接口
開(kāi)放源代碼
3、GOCW在VS中的環(huán)境配置
下載gocw_master,解壓后獲得兩個(gè)目錄文件。

其中,GOCW是類(lèi)庫(kù)文件,而WINFORM_DEMO是引用范例。
使用VS2017或者更高版本打開(kāi)WINFORM_DEMO.sln(或新建winform程序),在“引用”處添加GOCW的引用。

特別需要注意,正確編譯GOCW需要OpenCV的正確配置,所以需要正確設(shè)置include和lib,并且保證對(duì)應(yīng)版本的dll文件能夠被正確訪問(wèn)。


特別需要注意1:保證dll和csharp程序的.net目標(biāo)框架是一致的


特別需要注意2:保證dll和csharp程序的.net目標(biāo)框架是一致的
配置管理器中,所有項(xiàng)目版本全部使用64位

4、測(cè)試代碼
可以直接參考 WINFROM_DEMO

添加GOCW的頭文件
using GOCW;
編寫(xiě)GOCW調(diào)用代碼,你也可以根據(jù)需要吧Client的定義放在Form中。你實(shí)際使用過(guò)程中需要修改lena的地址。
private void button1_Click(object sender, EventArgs e)
{
Bitmap bmp = (Bitmap)Bitmap.FromFile("e:/template/lena.jpg");
GOCWClass client = new GOCWClass();
//調(diào)用圖像處理算法
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] bytes = ms.GetBuffer();
Bitmap bitmap = client.testMethod(bytes);
pictureBox1.Image = bitmap;
}
可以看到,實(shí)現(xiàn)了“灰度”變化。

5、原理簡(jiǎn)介
GOCW是通過(guò)CLR的方式進(jìn)行調(diào)用,關(guān)于CLR的原理這里不展開(kāi)。重點(diǎn)將一下你在哪里添加圖像處理算法,打開(kāi) GOCW.h文件
#pragma once
#include "opencv.hpp"
#using <system.drawing.dll>
using namespace System;
using namespace System::Data;
using namespace System::IO;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;
using namespace std;
namespace GOCW {
public ref class GOCWClass
{
public:
/////例子函數(shù)//////
//1.傳遞圖像
/* MemoryStream ms = new MemoryStream();
b.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] bytes = ms.GetBuffer();
Bitmap bitmap = client.testMethod(bytes);*/
Bitmap^ GOCWClass::testMethod(cli::array<unsigned char>^ pCBuf1);
//2.引用傳遞int
/*unsafe
{
int* value = stackalloc int[1];
value[0] = 0;
int iret = client.allTest(2, 3, value);
}*/
int GOCWClass::allTest(int a, int b, int* c);
//3.引用傳遞字符串
System::String^ GOCWClass::allTestStr(System::String^ inputStr);
/////業(yè)務(wù)函數(shù)//////
/*unsafe
{
int* value = stackalloc int[1];//返回代碼
value[0] = 0;
bitmap = client.fetchresult(bytes, value);//調(diào)用來(lái)自GOClrClasslibrary圖像處理算法
if (value[0] == 0)//0真1假
{
res = true;
}
else
{
res = false;
}
}*/
Bitmap^ GOCWClass::fetchresult(cli::array<unsigned char>^ pCBuf1, int* errorCode);
};
}
這里以“三明治”的方法將各種實(shí)現(xiàn)的方法進(jìn)行了申明,具體的實(shí)現(xiàn)在GOCW.cpp中,比如我們舉一個(gè)例子。
//1.傳遞圖像
Bitmap^ GOCWClass::testMethod(cli::array<unsigned char>^ pCBuf1)
{
////////////////////////////////將輸入cli::array<unsigned char>轉(zhuǎn)換為cv::Mat/////////////////////////
pin_ptr<System::Byte> p1 = &pCBuf1[0];
unsigned char* pby1 = p1;
cv::Mat img_data1(pCBuf1->Length, 1, CV_8U, pby1);
cv::Mat img_object = cv::imdecode(img_data1, cv::IMREAD_UNCHANGED);
if (!img_object.data)
return nullptr;
////////////////////////////////////////////OpenCV的算法處理過(guò)程////////////////////////////////////
Mat draw = img_object.clone();
cvtColor(draw, draw, COLOR_BGR2GRAY);
cvtColor(draw, draw, COLOR_GRAY2BGR);
/////////////////////////將cv::Mat轉(zhuǎn)換為Bitmap(只能傳輸cv_8u3格式數(shù)據(jù))///////////////////////////////
if (!draw.data)
return nullptr;
Bitmap^ bitmap = MatToBitmap(draw);
return bitmap;
}
在這段代碼中
Mat draw = img_object.clone(); cvtColor(draw, draw, COLOR_BGR2GRAY); cvtColor(draw, draw, COLOR_GRAY2BGR);
是具體業(yè)務(wù)函數(shù),可以根據(jù)實(shí)際算法要求進(jìn)行修改。關(guān)于參數(shù)的傳入傳出,在其他幾個(gè)函數(shù)中都有說(shuō)明。
6、初步小結(jié)
雖然GOCW相比較OpenCVSharp復(fù)雜一點(diǎn),但是它能夠和現(xiàn)有系統(tǒng)更緊密結(jié)合,優(yōu)勢(shì)也非常明顯。如果你首先是圖像處理開(kāi)發(fā)者,需要為算法尋找一個(gè)可以運(yùn)行的平臺(tái),那么GOCW基于CLR的封裝形式,肯定更適合你!
感謝閱讀至此,希望有所幫助!
以上就是如何在C#中使用OpenCV(GOCW使用教程)的詳細(xì)內(nèi)容,更多關(guān)于在C#中使用OpenCV(使用GOCW)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#使用WebClient實(shí)現(xiàn)上傳下載
這篇文章介紹了C#使用WebClient實(shí)現(xiàn)上傳下載的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
c#語(yǔ)言使用Unity粒子系統(tǒng)制作手雷爆炸
這篇文章主要為大家介紹了Unity的粒子系統(tǒng)由粒子發(fā)射器、粒子動(dòng)畫(huà)器、粒子渲染器組成,通過(guò)使用一或兩個(gè)紋理多次繪制,創(chuàng)造一個(gè)混沌的效果,通過(guò)復(fù)習(xí)粒子系統(tǒng)做一個(gè)手雷和實(shí)彈投擲現(xiàn)場(chǎng)2022-04-04
C# ADO.NET 離線查詢(xún)的實(shí)現(xiàn)示例
這篇文章主要介紹了C# ADO.NET 離線查詢(xún)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
C#實(shí)現(xiàn)簡(jiǎn)單的窗口抖動(dòng)
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)簡(jiǎn)單的窗口抖動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
C#使用iTextSharp封裝的PDF文件操作類(lèi)實(shí)例
這篇文章主要介紹了C#使用iTextSharp封裝的PDF文件操作類(lèi),實(shí)例分析了C#操作pdf文件的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03

