[置顶] 将C++ IplImage 图像用C#读取(二)


上一篇 将C++ IplImage 图像用C#读取 的方法只适用于自己的电脑,而如果是将工程放到别的计算机,debug版本可以工作

 release 版本就不能正常工作了,原因在于指针。具体的可以自己学习了解。(目前发现,部分电脑能用,部分不能用,有知道的可以告诉我下是什么问题,谢谢了

-----已经解决



因为少了一个tbb.dll,现在别人电脑可以使用了。但是单独的dependency看不出来,后来用的是procexp,对比别人的电脑和我的电脑dll的差别看出来的,上一篇的方法应该没有问题)

这次我换一种方法,供大家参考。

此方法经过其他机器的测试

CvMat 可以用类似的方法转换。

dll 代码

#include "stdafx.h"

#define DLL_API extern "C" _declspec(dllexport)   
#include <opencv2\opencv.hpp>

DLL_API IplImage* _stdcall test(char* fileName)
{
	IplImage* src = cvLoadImage(fileName);
	return src;
}

 测试程序

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.Util;
using System.Runtime.InteropServices;
namespace 1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("1.dll")]
       // unsafe
        public static extern IntPtr test(string fileName);  

        //unsafe
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog open = new OpenFileDialog();
            if (open.ShowDialog() == DialogResult.OK)
            {
                IntPtr pp = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MIplImage)));
                pp = test(open.FileName);
                MIplImage d = (MIplImage)Marshal.PtrToStructure((IntPtr)(pp.ToInt32()), typeof(MIplImage));
                IntPtr aa = new IntPtr();
                aa = d.imageData;
                int width = d.width;
                int step = d.widthStep;
                int height = d.height;
                using (Image<Bgr, byte> src = new Image<Bgr, byte>(width, height, step, aa))
                {
                   pictureBox1.Image = src.ToBitmap();
                }
            }

        }
    }
}

[置顶] 将C++ IplImage 图像用C#读取(二)_第1张图片



下面是我按照C++的格式对应写的结构体
        [StructLayout(LayoutKind.Sequential)]
        public struct MIplImage
        {

            //
            // 摘要:
            //     sizeof(IplImage)
            public int nSize;
            //
            // 摘要:
            //     version (=0)
            public int ID;
            //
            // 摘要:
            //     Most of OpenCV functions support 1,2,3 or 4 channels
            public int nChannels;
            //
            // 摘要:
            //     ignored by OpenCV
            public int alphaChannel;
            //
            // 摘要:
            //     pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S,
            //     IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported
            public IPL_DEPTH depth;
            //
            // 摘要:
            //     ignored by OpenCV
            public byte colorModel0;
            //
            // 摘要:
            //     ignored by OpenCV
            public byte colorModel1;
            //
            // 摘要:
            //     ignored by OpenCV
            public byte colorModel2;
            //
            // 摘要:
            //     ignored by OpenCV
            public byte colorModel3;
            //
            // 摘要:
            //     ignored by OpenCV
            public byte channelSeq0;
            //
            // 摘要:
            //     ignored by OpenCV
            public byte channelSeq1;
            //
            // 摘要:
            //     ignored by OpenCV
            public byte channelSeq2;
            //
            // 摘要:
            //     ignored by OpenCV
            public byte channelSeq3;
            //
            // 摘要:
            //     0 - interleaved color channels, 1 - separate color channels.  cvCreateImage
            //     can only create interleaved images
            public int dataOrder;
            //
            // 摘要:
            //     0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style)
            public int origin;
           
            // 摘要:
            //     Alignment of image rows (4 or 8).  OpenCV ignores it and uses widthStep instead
            public int align;
            //
            // 摘要:
            //     image width in pixels
            public int width;
            //
            // 摘要:
            //     image height in pixels
            public int height;
            //
            // 摘要:
            //     image ROI. when it is not NULL, this specifies image region to process
            public IntPtr roi;
            //
            // 摘要:
            //     must be NULL in OpenCV
            public IntPtr maskROI;
            //
            // 摘要:
            //     ditto
            public IntPtr imageId;
            //
            // 摘要:
            //     ditto
            public IntPtr tileInfo;
            //
            // 摘要:
            //     image data size in bytes (=image->height*image->widthStep in case of interleaved
            //     data)
            public int imageSize;
            //
            // 摘要:
            //     pointer to aligned image data
            public IntPtr imageData;
            //
            // 摘要:
            //     size of aligned image row in bytes
            public int widthStep;
            //
            // 摘要:
            //     border completion mode, ignored by OpenCV
            public int BorderMode0;
            //
            // 摘要:
            //     border completion mode, ignored by OpenCV
            public int BorderMode1;
            //
            // 摘要:
            //     border completion mode, ignored by OpenCV
            public int BorderMode2;
            //
            // 摘要:
            //     border completion mode, ignored by OpenCV
            public int BorderMode3;
            //
            // 摘要:
            //     border const, ignored by OpenCV
            public int BorderConst0;
            //
            // 摘要:
            //     border const, ignored by OpenCV
            public int BorderConst1;
            //
            // 摘要:
            //     border const, ignored by OpenCV
            public int BorderConst2;
            //
            // 摘要:
            //     border const, ignored by OpenCV
            public int BorderConst3;      
            //
            // 摘要:
            //     pointer to a very origin of image data (not necessarily aligned) - it is
            //     needed for correct image deallocation
            public IntPtr imageDataOrigin;      
        }

对于不用EMGUCV的人  可以自己复制一个MIplImage 的结构体



这里还需要DEPTH这个类

 public enum IPL_DEPTH
    {
        // 摘要:
        //     1bit unsigned
        IPL_DEPTH_1U = 1,
        //
        // 摘要:
        //     8bit unsigned (Byte)
        IPL_DEPTH_8U = 8,
        //
        // 摘要:
        //     16bit unsigned
        IPL_DEPTH_16U = 16,
        //
        // 摘要:
        //     32bit float (Single)
        IPL_DEPTH_32F = 32,
        //
        // 摘要:
        //     double
        IPL_DEPTH_64F = 64,
        //
        // 摘要:
        //     indicates if the value is signed
        IPL_DEPTH_SIGN = 0x80000000,
        //
        // 摘要:
        //     8bit signed
        IPL_DEPTH_8S = IPL_DEPTH_SIGN| 8,
        //
        // 摘要:
        //     16bit signed
        IPL_DEPTH_16S = IPL_DEPTH_SIGN|16,
        //
        // 摘要:
        //     32bit signed
        IPL_DEPTH_32S = IPL_DEPTH_SIGN|32,
    }

对于灰度图像需要添加一个类方法:

public static class CvToolbox
    {

       // #region Color Pallette
        /// <summary>
        /// The ColorPalette of Grayscale for Bitmap Format8bppIndexed
        /// </summary>
        public static readonly ColorPalette GrayscalePalette = GenerateGrayscalePalette();

        private static ColorPalette GenerateGrayscalePalette()
        {
            using (Bitmap image = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
            {
                ColorPalette palette = image.Palette;
                for (int i = 0; i < 256; i++)
                {
                    palette.Entries[i] = Color.FromArgb(i, i, i);
                }
                return palette;
            }
        }
    }


调用方法只需更改以下几行,速度很快,根据EMGU改编的
            aa = d.imageData;
            int height = d.height;
            int step = d.widthStep;
            Bitmap img = new Bitmap(width, height, step, System.Drawing.Imaging.PixelFormat.Format8bppIndexed, aa);
            img.Palette = CvToolbox.GrayscalePalette;
            bigImage.Image = img;





你可能感兴趣的:(图像,opencv,IplImage,C#读取,C#读取C++)