1

まず第一に、私はOpenCVにまったく慣れていません。私は約1週間成功せずに努力していますが、決して成功しないようです。そのため、同じ問題に直面した人に助けを求めなければなりません。

基本的に次のことを行うVC#2010で非常に単純なアプリケーションを構築したいと思います。

  • JPEG画像を読み取り、ビットマップ変数に保存します
  • ビットマップ変数をVC++dllにカプセル化された関数に送信します
  • VC ++ dllで、画像に対して簡単な操作を実行します(たとえば円を描く)
  • 変更した画像をVC#アプリに返し、PictureBoxに表示します

VC#のコード:

[DllImport("CppTestDll.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern Bitmap testImage(Bitmap img);

private void button1_Click(object sender, EventArgs e)
    {
        // read the source jpeg from disk via a PictureBox
        Bitmap bmpImage = new Bitmap(pictureBox1.Image);

       //call the function testImage from the VC++ dll
   //  and assign to another PictureBox the modified image returned by the dll
        pictureBox2.Image = (System.Drawing.Image)testImage(bmpImage);
    }

VC ++ dllのコード:

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>

#include <stdio.h>

using namespace cv;
using namespace std;

    __declspec(dllexport) char* testImage(char *image)
    {
        //the image is 640x480
        //read the jpeg image into a IplImage structure
       IplImage *inputImg= cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 3); 
       inputImg->imageData = (char *)image;

        // I also tried to copy the IplImage to a Mat structure
        // this way it is copying onl the header
        // if I call Mat imgMat(inputImg, true); to copy also the data, I receive an error for Memory read access
        Mat imgMat(inputImg);

        // no matter which circle drawing method I choose, I keep getting the error
        //  AccessViolationException was unhandled. Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

        cvCircle(inputImg,Point(100,100),100,cvScalar(0, 0, 255, 0),1,8,0);
        circle(imgMat,Point(100,100),100,Scalar(0, 0, 255, 0),1,8,0);

        // I tried both ways to return the image
        // If I try to modify the image I receive the above described error
        // If I don't modify the input image, I can send back the original image, but it is useless

        //return (char *)imgMat.data;
        return (char *)inputImg->imageData;
    }

私がどこを間違えているのか教えていただけませんか。または、その方法を示す小さなサンプルコードを提供しますか?

更新 VC++dll内でcvImageLoadを使用してディスクからjpegファイルを読み取ると、描画操作が機能し、変更された画像を返すことができます。問題は、画像を正しい方法でdllに送信することです。何か提案はありますか?

また 、私はこのようにVC++でdllを変更しました

__declspec(dllexport) char* testImage(uchar* image)
{
        uchar *pixels = image;
        Mat  img(480,640,CV_8UC3,pixels);

        if (!img.data)
        {
            ::MessageBox(NULL, L"no data", L"no data in imgMat mat", MB_OK);
        }

        line(img,Point(100,100),Point(200,200),Scalar(0, 0, 255, 0),1,8,0);
        return (char *)img.data;
    }

線画操作は失敗しますが、線画にコメントを付けると画像が返ってきます。

どうしたの?

4

1 に答える 1

1

ビットマップ画像をchar*として受け取るtestImage関数に渡すと、キャストの問題が発生する可能性があります。私がそう思う理由は、画像データがなく、そこに到達しようとすると、この種のエラーが発生するためです。それをデバッグして、データがイメージで利用可能かどうか、または使用できるかどうかを確認できますか

if(!imgMat.data)
   //error. Print something or break

編集

私はC#でOpencvを使用しませんでしたが、通常、人々はopencvsharp、emgu、または他の代替手段を使用します。しかし、あなたのやり方は不適切のようです。C#でopencvdllを使用するには; 彼らはそれがラッパーかそのようなものを必要とすると言います。彼らはC#のためにEmguを提案します。

また、COM相互運用機能を有効にしてdllをコンパイルしましたか?(C#でc ++ dllを使用するには、COMとしてコンパイルする必要があると言われています)。しかし、私はそれがまだ機能するとは思わない。これらすべてのEmgu、opencvdotnet、opencvsharpなどのラッパーの背後には理由があるはずです。右?

于 2012-09-06T06:58:46.797 に答える