Ask Your Question
1

How to properly convert Mat to Bitmap C++

asked 2017-10-02 06:22:35 -0600

Andriezel gravatar image

Hello,

I'm a student and I'm learning OpenCV (C++) and I'm having a weird question. I'm using OpenCV in C++/CLI and a C# Windows Form to show the output.

This is my plan on how to do this:

  1. Load Mat Image in C++ 2.
  2. Convert Mat to Bitmap
  3. Return the Bitmap from C++ to C# 4.
  4. Show the Bitmap on Windows Form.

Now I thought this was a good strategy but I got an error saying: 'Access Violation Exception'. So I tried to look for an answer but couldn't find it on the Web. I have all my projects in x64. The weird thing is that if I put 'imshow()' function in this method, I get a weird looking picture, but no errors.

This is the .cpp file:

Bitmap^ OpenCvWrapper::ApplyFilter() {
    Mat image = imread("C:/Users/Andries/Pictures/colored_squares.png");

    returnImg = ConvertMatToBitmap(image)
    return returnImg;
}


Bitmap^ OpenCvWrapper::ConvertMatToBitmap(cv::Mat matToConvert) {
    imshow("Window", matToConvert);
    Bitmap^ test = gcnew Bitmap(matToConvert.rows, matToConvert.cols, 4 * matToConvert.rows, System::Drawing::Imaging::PixelFormat::Format4bppIndexed, IntPtr(matToConvert.data));

    return test;
}

And this is my .cs file:

public partial class Form1 : Form
    {
        private Bitmap f;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpencvDotNet.OpenCvWrapper obj = new OpencvDotNet.OpenCvWrapper();
            f = obj.ApplyFilter();
            pictureBox1.Image = f;
    }

I can provide the header but I think that's not necessary as of now.

Now with this code I get the following output: image description

Please help.

Andries

edit retag flag offensive close merge delete

Comments

Please read the FAQ!

Basically the following types of questions are not allowed on this forum: [...]

(4) Questions about problems with openCV wrappers (EmguCV, JavaCV, OpenCVSharp, ...) or extension libraries (cvBlobsLib, opencvx, ...). Again these problems should be adressed to the proper fora.

Anyway, as a personal note, I don't recommend using C# with OpenCV...

kbarni gravatar imagekbarni ( 2017-10-02 08:10:00 -0600 )edit

Hi, thanks for replying but I'm not using any of these openCV wrappers. I'm just using C# as a GUI. Also, I don't use any extension libraries.

Andriezel gravatar imageAndriezel ( 2017-10-02 08:16:14 -0600 )edit

if you load an image using imread() (with no flags), it will be 24bit bgr.

so, your stride looks broken, and for sure it's not Format4bppIndexed (which is only a thing with bmp images)

(last, my 2 ct. : don't waste too much time on gui things. noone will see it anyway, your program won't work any better, you're only adding distraction to your code)

berak gravatar imageberak ( 2017-10-03 03:30:47 -0600 )edit

Hi berak, thanks for the comment. So if my stride is broken; how can I fix that? I thought 4 * image.rows is enough. I already tried every singe PixelFormat there was but I still get the same picture.

Well it's kind of a must to create a gui. People have to work with this gui.

Andriezel gravatar imageAndriezel ( 2017-10-03 06:38:23 -0600 )edit

stride is probably 3 x img.cols (if there is no padding required, idk)

and you need some pixelformat for 24bit

berak gravatar imageberak ( 2017-10-03 06:58:01 -0600 )edit

I already have my PixelFormat to 24 bit. I tried 3 * img.cols but that doesnt work. Now I tried saving my Bitmap right after I converted it from Mat to Bitmap and I received the following output: Image Please help.

Andriezel gravatar imageAndriezel ( 2017-10-03 07:48:25 -0600 )edit

Check the Stride property of the BitmapData object. The lines in C# are aligned on a certain number of pixels, so the first pixel of line N isn't at position N*bmpData.Width but N*bmpData.Stride.

kbarni gravatar imagekbarni ( 2017-10-03 08:45:24 -0600 )edit

@kbarni I don't get that actually. I checked the Stride in the C++ converted Bitmap object in the C# code and it says: 1024. But when I load the Bitmap image directly in C# it gives me a Stride of 1720. So I manually put the 1720 in the C++ conversion code, but I still get a weird image. I don't why.

Andriezel gravatar imageAndriezel ( 2017-10-04 05:20:21 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2017-10-18 09:23:26 -0600

Andriezel gravatar image

Okay so after a while I managed to get it working. What I did was the following:

  • I made cv::Mat image; as global variable, so in that way it doesn't remove itself from the memory when it's 'done', which is the case now. (Sorry, I should've known that. It is documented in the docs section of OpenCV.)

  • In the line where I return my Bitmap, I changed 4 * matToConvert.rows to matToConvert.step1(). Because what @berak said about the stride is broken is totally right and since I changed that line I didn't have any problems since.

Thanks.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-10-02 06:21:25 -0600

Seen: 16,675 times

Last updated: Oct 18 '17