【重要總結】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.

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