【重要总结】IntPtr、Image以及IplImage三者之间的相互转换

/******************************************************************************/
/***************************MIplImage&IntPtr&Image<,>***************************/
/******************************************************************************/


/*************************Image<,>转MIplImage和IntPtr*********************************/
Image<,>读入的scr图像,获得可以openCV处理的MIplImage&IntPtr型数据的方法 **************/
1、src.Ptr 获得IntPtr型数据;                                          **************/
2、src.MIplImage获得IplImage结构;                                        **************/
src.MIplImage.imageData获得结构内的数据;                                **************/
/*************************************************************************************/


/***********************************************************IntPtr转成MIplImage格式*********************************************************/
cvLoadImage导入的图像img是IntPtr类型无法直接进行像素点操作。                                                                     ***********/
首先要进行格式的转化,把IntPtr型转换成MIplImage:                                                                                 ***********/
                                                                                                                                 ***********/
Emgu.CV.Structure.MIplImage MIpImg =                                                                                             ***********/
    (Emgu.CV.Structure.MIplImage)System.Runtime.InteropServices.Marshal.PtrToStructure(img, typeof(Emgu.CV.Structure.MIplImage));***********/
                                                                                                                                 ***********/
然后在C#中使用unsafe中指针操作:                                                                                                 ***********/
nPixel = (int)((byte*)MIpImg.imageData + MIpImg.widthStep * i)[j];                                                               ***********/
/*******************************************************************************************************************************************/


/*****************************************IntPtr转Image<,>***********************************************************************/
假设载入的src图像是IntPtr类型                                                                                     *************/
//先创建一个空白的dst                                                                                               *************/
Image<,> dst = new Image<,>(new System.Drawing.Size(width, height));                                                *************/
                                                                                                                    *************/
//调用CvInvoke.cvCopy(),注意dst.IntPtr的用法                                                                       *************/
CvInvoke.cvCopy(src, dst.IntPtr, IntPtr.Zero);                                                                      *************/
                                                                                                                    *************/
//cvCopy语法                                                                                                      *************/
public static void cvCopy(IntPtr src,                                                                               *************/
                          IntPtr des,                                                                               *************/
                          IntPtr mask)                                                                              *************/
Parameters:                                                                                                     *************/
src                                                                                                                 *************/
Type: System.IntPtr                                                                                                 *************/
The source array                                                                                                    *************/
des                                                                                                                 *************/
Type: System.IntPtr                                                                                                 *************/
The destination array                                                                                               *************/
mask                                                                                                                *************/
Type: System.IntPtr                                                                                                 *************/
Operation mask, 8-bit single channel array; specifies elements of destination array to be changed                   *************/
                                                                                                                    *************/
//示例——————cvCopy或者MIplImage                                                                                     *************/
//scr是由OpenCV读取的图片,它实际上是一个指针IntPtr,如果想把它转为Bitmap,                                           *************/
//需要一个中间步骤:创建一个Emgu.CV.Image对象,                                                                     *************/
//再用cvCopy把数据拷贝过去,然后再调用ToBitmap()方法转换即可。                                                        *************/
第一种方法:                                                                                                      *************/
IntPtr scr = CvInvoke.cvLoadImage(filename, Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_ANYCOLOR);                 *************/
Image<Bgr, byte> dst = new Image<Bgr, byte>(CvInvoke.cvGetSize(image));                                             *************/
CvInvoke.cvCopy(scr, dst.IntPtr, IntPtr.Zero);                                                                      *************/
pictureBox1.Image = dst.ToBitmap();                                                                                 *************/
                                                                                                                    *************/
第二种方法:                                                                                                      *************/
IntPtr scr = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(Histimg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);         *************/
CvInvoke.cvCanny(Histimg, scr, trackBar1.Value, trackBar1.Value * 3, 3);                                            *************/
MIplImage scr1 = (MIplImage)Marshal.PtrToStructure(scr, typeof(MIplImage));                                         *************/
Image<Gray, Byte> dst = new Image<Gray, Byte>(scr1.width, scr1.height, scr1.widthStep, scr1.imageData);             *************/
pictureBox.Image = dst.ToBitmap();                                                                                  *************/
/********************************************************************************************************************************/



/***************************************IntPtr和IplImage的作用******************************************/
IntPtr img1 = CvInvoke.cvCreateImage(new Size(256, 256),                                    ************/
IPL_DEPTH.IPL_DEPTH_16U, 1);                                                                ************/
                                                                                            ************/
It shows the same effects in OpenCV code:                                                   ************/
                                                                                            ************/
IplImage* img1 = cvCreateImage(cvSize(256, 256), IPL_DEPTH_16U, 1);                         ************/
                                                                                            ************/
Both of them will create an image with the size of 256 x 256 pixels, the depth of 16 bit    ************/
unsigned, and the channel 1.                                                                ************/
/*******************************************************************************************************/



















//canny算子边缘检测
IntPtr imgCanny = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(Histimg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);

CvInvoke.cvCanny(imgHist, imgCanny, trackBar1.Value, trackBar1.Value * 3, 3);

MIplImage img = (MIplImage)Marshal.PtrToStructure(imgCanny, typeof(MIplImage));

Image<Gray, Byte> img1 = new Image<Gray, Byte>(img.width, img.height, img.widthStep, img.Data);

pictureBox5.Image = img1.ToBitmap();


IntPtr img1 = CvInvoke.cvCreateImage(new Size(256, 256),
IPL_DEPTH.IPL_DEPTH_16U, 1);

It shows the same effects in OpenCV code:

IplImage* img1 = cvCreateImage(cvSize(256, 256), IPL_DEPTH_16U, 1);

Both of them will create an image with the size of 256 x 256 pixels, the depth of 16 bit
unsigned, and the channel 1.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章