Why am I Getting distorted images after sending them from C# to OpenCV in C++? [closed]

asked 2017-08-17 07:35:20 -0500

Niessoh gravatar image

I created a C DLL out of my C++ class which uses OpenCV for image manipulations and want to use this dll in my C# application. Currently, this is how I have implemented it :

#ifdef CDLL2_EXPORTS
#define CDLL2_API __declspec(dllexport)
#else
#define CDLL2_API __declspec(dllimport)
#endif

#include "../classification.h" 
extern "C"
{
    CDLL2_API void Classify_image(unsigned char* img_pointer, unsigned int height, unsigned int width, char* out_result, int* length_of_out_result, int top_n_results = 2);
    //...
}

C# related code :DLL Import section:

//Dll import 
[DllImport(@"CDll2.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void Classify_Image(IntPtr img, uint height, uint width, byte[] out_result, out int out_result_length, int top_n_results = 2);

The actual function sending the image to the DLL:

//...
//main code 
private string Classify(int top_n)
{
    byte[] res = new byte[200];
    int len;
    Bitmap img = new Bitmap(txtImagePath.Text);
    BitmapData bmpData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), 
                                      ImageLockMode.ReadWrite,  
                                      PixelFormat.Format24bppRgb);
    Classify_Image(bmpData.Scan0, (uint)bmpData.Height, (uint)bmpData.Width, res, out len, top_n);
    img.UnlockBits(bmpData); //Remember to unlock!!!
    //...
}

and the C++ code in the DLL :

CDLL2_API void Classify_Image(unsigned char* img_pointer, unsigned int height, unsigned int width,
                              char* out_result, int* length_of_out_result, int top_n_results)
    {
        auto classifier = reinterpret_cast<Classifier*>(GetHandle());

        cv::Mat img = cv::Mat(height, width, CV_8UC3, (void*)img_pointer, Mat::AUTO_STEP);

        std::vector<Prediction> result = classifier->Classify(img, top_n_results);

        //...
        *length_of_out_result = ss.str().length();
    }

This works prefectly with some images but it doesnt work with others, for example when I try to imshow the image in the Classify_Image, right after being created form the data sent by C# application, I am faced with images like this : problematic example:
image description

fine example :
image description

Here are the original images for further investigations(may be nsfw for some people so I place the link) :
http://answers.opencv.org/upfiles/150...
http://answers.opencv.org/upfiles/150...

My own thought about the cause of the issue, is I am creating the image regardless of its true type, (setting all images to CV_8UC3 and Mat::AUTO_STEP. thats why some images are fine and some others are not. The problem is, I dont know how I'm supposed to assign the correct type to each image at creation time back in C++. (if thats the cause for such issue, if it is not then I have no idea what else could be doing this) Any help is greatly appreciated .

edit retag flag offensive reopen merge delete

Closed for the following reason question is off-topic or not relevant by Tetragramm
close date 2017-08-17 20:34:19.589991

Comments

We don't support C#, but have you checked the pitch? IE: the first image is 1414 pixels wide. Perhaps there is a gap in the memory, and each row is 1424 apart or something.

Tetragramm gravatar imageTetragramm ( 2017-08-17 17:34:05 -0500 )edit

Thank you @Tetragramm. yes part of the issue was the step size. there are still other issues for example, when I resize the image in C# and pass it to the dll, although the full image works, the resized one has scan lines in it! like an old black and white TV with vertical scan lines! (here is screeshot : http://imgur.com/a/UvkhH) if I use opencv interal resize, its fine, if I send in the full size image it works, but when I use a resized one this is what I get ) I'll dig further and if I come up with an answer i update this post. Thank you for the heads-up

Niessoh gravatar imageNiessoh ( 2017-08-17 20:05:39 -0500 )edit