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

    xiaoxiao2021-04-18  69

    /******************************************************************************/ /***************************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.
    转载请注明原文地址: https://ju.6miu.com/read-675579.html

    最新回复(0)