Emgu CV Lesson 1

配置EMGU CV C# 

一:示例代码

下述文章是为初学者介绍一步步搭建EMGUcv开发环境而设置的,这篇文章会让你配置过程更加简单化。EMGU是用更加安全的纯C#写的对OpenCV的一层包装。EMGU是针对C#开发者的针对机器视觉的的开放了OpenCV库。OpenCV最初由Intel开发,现在由Willow Garage维护。
x86和x64版本的EMGUcv都可以在SourceForge上可以下载。
EMGU是对c++代码的包装,因此有两种DLL‘s的可以使用。即EMGU表达法的引用和可变的OpenCv的DLL。因此设置第一个工程时初学者常常会感到迷惑。
如果你已经下载了EMGU源码包的话,你首先应该阅读“A Basic Program”这篇文章。你拿到EMGU的代码可能会遇到 The EMGU.CV.Invoke Exception and Troubleshooting的错误。

三:储备知识

假设你已经有了基本的C#编程经验并可以创建C#工程。并且你也已经下载了最新的包含了HelloWorld示例的EMGU平台

四:基本要求

你的工程需要引用你需要的一切DLL引用的库。创建一个任意命名的C# 的Windows Form Application程序,所有提到的DLL文件都在X:\bin文件夹目录下。(X是指你安装EMGU所在的目录)

下面是三个你需要引用的三个DLL文件:Emgu.CV.dll、Emgu.CV.UI.dll、Emgu.Util.dll
可以通过右键点击你的工程或者在解决方法上添加引用。
如图所示

或者使用menu 选项中的Project -》Add Referrence,选择所需的DLL后单击OK选项

这时你会在解决方案中的Reference文件夹看见你添加的DLL引用库,上述提到的三个EMGU C#引用。这并不需要你有任何的图像处理方面的额知识。
现在你可以使用任何在这些DLL中的类了。这些引用取决于你需要用于做什么样的图像处理。看这个例子你需要将一下的代码添加到Form1.cs的代码最上面的引用语句前。
 using Emgu.CV;
 using Emgu.Util;
 using Emgu.CV.Structure;

五:首选的方法

相对于对于复杂的C++库,加载、显示、获取图像数据可以变得更加简单,你只需要添加两个文件即可。

opencv_core220.dll    
opencv_imgproc220.dll

Note:220代表的是你的EMGU的版本号,可能或由你的版本号的不同而不一样。

这两个文件你不能直接像EMGU库文件那样引用。你需要将这两个文件添加到你的工程中。有两种方法,右键点击在解决方法中的你的工程名字通过Add-》Existing Item选中上述两个文件,这两个文件位于EMGU解压后的\bin目录下。

提示:如果你发现不好找这两个文件,可以使用文件过滤的方法


现在你可以在你的解决方案中看见这两个文件了。你可以通过Ctrl+鼠标左键选择这两个文件改变他们的属性(或者单独拷贝),你可以看到属性里面的Copy to Output Directory.将”Do not copy“属性改成“Copy always”。
 
如果你使用x64兼容模式来编译你需要在你进行图像处理前将编译模式选择成x64的模式。这样是首选的方法,这对于你从Debug改到Release时同样有效,保证没有错误发生。你可以跳转到“A Basic Program”小结查看图示。

六:其次可选的方法

虽然不是首选的方法往往是最简单的,如果你有一个复杂的工程结构,这样可以防止你的解决方案资源管理器看起来非常混乱。只需要将上述的opencv_core220.dll 和opencv_imgproc220.dll文件直接拷贝到你的工程文件项目的\bin\Debug或者\bin\Release文件夹。虽然目前的好处在这里可能你不太清楚,想象一下你的解决方案管理器中添加了另外34个DLL文件的情形这是很稀少的情况。

七:x64架构和EMGU.CV.Invoke异常

如果你的系统是x64架构,你必须下载单独相应的DLL文件,建立工程的步骤和上述的步骤一样,但你需要一个额外的编译参数。右键单击解决方案的中的项目文件,并在地步选择“属性”,将生成选项卡中下拉菜单从x86换到x64。


提示:如果你用的是Visual Studio Express版本,你可能会看不到这个选项,你可以通过菜单栏的“工具-》选项”,在里面找到Project and solution中找到Show advanced build configuration勾选项。

如果你不这么做的话,你会遇到EMGU.CV.Invoke异常。

八:A Basic Program

EMGU为你提供了一种简单的方式加载图像并在一个图片框中显示出来,并将展示如何获取图像数据和图像格式的转换。
当你下载x86格式示例代码时,你会发现在你的解决方案资源管理器中发现三个黄色的引用警告,你需要重新添加对他们的引用,怎么引用可以参考”基本要求“小节,
现已有一个Button 、PictureBox添加到main Form上,默认名称并没有改变,功能是当我们点击Button,我们打开一个文件对话框,选择图像,并加载显示到PictureBox上。
    private void button1_Click(object sender, EventArgs e)
    {
        OpenFileDialog Openfile = new OpenFileDialog();
        if (Openfile.ShowDialog() == DialogResult.OK)
        {
            Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
            pictureBox1.Image = My_Image.ToBitmap();
        }
    }
  

这段代码非常简单,主要是通过名为Openfile的OpenFileDialog用于选择图像文件。图像被一个名为My_Image的色彩Image对象读取。这要求图像时Bitmap格式,所以通过My_Image对象的.ToBitmap()方法来实现。

九:一个小的图像处理的例子

这个小的稍高级的工程可能会遇到像“A Basic Program”那样的警告。引用需要重新替换。在这个程序中演示的是将一个Image从彩色变成灰阶,通过处理每个单元的图像像素。而这个压缩图像光谱数据并不是最有效的,但是却是一个获取图像数据属性的一个很好地例子。

一个小的图像变换

图像变换在EMGU里是复杂的。在这个例子中一个Bgr彩色图像将或被转换灰色的灰阶图像。
 Image<gray,byte> gray_image = My_Image.Convert<gray,byte>();

尽管如此你可以逐渐利用不同的图像的深度(Tdepth)还不是Byte。这个方法的问题是你每次调用只能转换一个depth。假如说我们希望从Image<bgr,byte>转换到Image<gray,double>,你可以利用下列代码
Image<Gray,byte> gray_image = My_Image.Convert<Gray,byte>();
Image<Gray,double> gray_image = My_Image.Convert<Gray,double>();
//or alternatively in one line
Image<Gray,> gray_image = My_Image.Convert<Gray,byte>().Convert<Gray,double>();
//alternatively
Image<Gray,Byte> gray_image = My_Image.Convert<Bgr,double>().Convert<Gray,double>();

获取图像数据

有几种不同的方法获取图像数据并赋值给他。有两种可用的方法,直接通过图像数据的属性获取。下面将演示这两种方法。当获取图像属性时,需要考虑图像的光谱深度,灰阶图像将会有1个深度的Image spectrum depth,用[x,y,0]来表示,case图像有三个深度,[x,y,0],[x,y,1],[x,y,2]分别代表蓝、绿、红
假设我们希望对一个坐标为[0,0]像素赋值。

//Colour Image
My_Image[0, 0] = new Bgr(Color.Red);

//Gray Image
gray_image[0, 0] = new Gray(200);

或者使用数据属性
//Colour Image
Color R = Color.Red;
My_Image.Data[0,0,2] = R.R; //Write to the Red Spectrum
My_Image.Data[0,0,1] = R.G; //Write to the Green Spectrum
My_Image.Data[0,0,0] = R.B; //Write to the Blue Spectrum

//Gray Image
gray_image[0, 0] = new Gray(200);

写数据到一个像素相对简单但是读取一个像素
//Colour Image
Bgr my_Bgr = My_Image[0, 0];

//Gray Image
Gray my_Gray = gray_image[0, 0];

现在在许多情况下不能使用Bgr和Gray,所以需要转换
//BGR to Color
Color my_colour = Color.FromArgb((int)value.Red, (int)value.Blue, (int)value.Green);

//Gray to int
int my_intensity = (int) my_Gray.Intensity;

你可能会注意到每个值都会出现数据丢失,因为默认是以double型存储的。尽管对于这个例子更好的方法是通过图像属性来获取数据。如果你想读取图像数据,并没有要求在灰阶和整数之间转换。你可以直接读取图像数据并使用。
//Colour
Color my_colour = Color.FromArgb(My_Image.Data[0, 0, 0], 
My_Image.Data[0, 0, 1], My_Image.Data[0, 0, 2]);

//Gray Image
int my_intensity = gray_image.Data[0, 0, 0];

再循环中处理图像会更加方便,要研究如何通过循环实现图像处理,请下载Little More Image Processing代码。

DLLNotFound Exception and Troubleshooting 0x8007007E异常

Unable to load DLL 'opencv_highgui220': The specified module could not be found. (Exception from HRESULT: 0x8007007E) 
这个异常通常当你获取一个Web摄像头的图像时出现,解决办法非常简单,你只需要按照上述的步骤文件属性“copy to Output Directory”换成“Copy always”,或者直接拷贝到运行程序的目录下。
Unable to load DLL 'cvextern': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
这个错误不能仅仅添加cvextern.dll文件就解决了,你可能还需要将以下文件同时添加并拷贝
cudart64_32_16.dll  
cufft64_32_16.dll 
cvextern.dll 
npp64_32_16.dll 
opencv_calib3d220.dll 
opencv_contrib220.dll 
opencv_core220.dll  
opencv_features2d220.dll 
opencv_flann220.dll 
opencv_gpu220.dll 
opencv_highgui220.dll 
opencv_imgproc220.dll 
opencv_legacy220.dll 
opencv_ml220.dll 
opencv_objdetect220.dll 
opencv_video220.dll 
任何类似的错误你都可以通过上述方法来解决,如果你仍然没有解决你可以向论坛求助。

System.TypeInitializationException:  Convertion from Image<Emgu.CV.Structure.Bgr*,System.Byte*> to Image<Emgu.CV.Structure.Structure.Bgr*,System.Byte*> is not supported by OpenCV 

*表示相关的图像深度或者数据类型,这个错误是在2.3.*版本中出现的,拷贝了 opencv_imgproc***.dll或者opencv_core***.dll到项目的输出文件中。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值