将C++ IplImage 图像用C#读取(二)

24 篇文章 0 订阅
12 篇文章 0 订阅
本文提供了一种将C++中的IplImage图像转换为C#兼容的MIplImage结构体的方法,解决了工程在不同计算机上运行时遇到的指针问题。通过使用DllImport和Marshal进行内存管理,实现了一个适用于多种操作系统的图像处理功能。
摘要由CSDN通过智能技术生成


上一篇 将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++的格式对应写的结构体
        [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;



1、将Mat转换为IplImage

//! converts header to IplImage; no data is copied
    operator IplImage() const;

举例:Mat img;

            IplImage *src;

             src=&IplImage(img);

2、将IplImage转换为Mat

//! converts old-style IplImage to the new matrix; the data is not copied by default
    Mat(const IplImage* img, bool copyData=false);



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值