Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
343 views
in Technique[技术] by (71.8m points)

c++ - How to display a cv::Mat in a Windows Form application?

I tried to use imwrite to successfully to display an image on a Windows Form, but it damages the disk, so I need a better way to do this.

Below, is my current code, which writes the image temporarily to the hard drive:

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {

        namedWindow("video",0);
        VideoCapture cap(0);
        flag = true;
        while(flag){
            Mat frame;
            cap >> frame; // get a new frame from camera
            **imwrite("vdo.jpg",frame);**
            this->panel1->BackgroundImage = System::Drawing::Image::FromFile("vdo.jpg");

            waitKey(5);
            delete panel1->BackgroundImage;
            this->panel1->BackgroundImage = nullptr;

        }
    }

When I try to use the OpenCV Mat that is in memory, I cannot get it to work. The following code snippets are what I have tried so far:

this->panel1->BackgroundImage = System::Drawing::Bitmap(frame);

or

this->panel1->BackgroundImage = gcnew System::Drawing::Bitmap( frame.widht,frame.height,System::Drawing::Imaging::PixelFormat::Undefined, ( System::IntPtr ) frame.imageData);

I want to display frame in this code without using imwrite. How do I accomplish this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It is definitely a good idea to get away from writing the image to a file and then immediately reading back onto a control. It is quite inefficient as the hard drive is the slowest memory device in the system usually.

I do not believe you are using the correct Bitmap constructor in your example above. You should probably be using this constructor definition. Also, telling the Bitmap object that the PixelFormat is undefined is probably not helping things either. I'm assuming you have a color camera that is returning a CV_8UC3 matrix (i.e., your PixelFormat == Format24bppRgb).

How about try a call like this:

this->panel1->BackgroundImage = gcnew System::Drawing::Bitmap(frame.size().width,
                                                              frame.size().height,
                                                              frame.step,
                                                              PixelFormat::Format24bppRgb,
                                                              (IntPtr)frame.data);

Also, remember that OpenCV natively stores color in BGR format. So, you may need to swap the red and blue channels to get the data to look right.

Hopefully, that will get you started!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...