[OpenCV|C++|CLR] 如何在CLR視窗中,把OpenCV的影像格式(IplImage)顯示在PictureBox中

之前因為實驗室學妹要當助教的關係,希望透過CLR來寫視窗介面,並希望能夠把OpenCV影像格式可以顯示在視窗的PictureBox上,而不是使用OpenCV內建的imshow

而這時候我們便要把OpenCV的影像格式轉換成PictureBox吃的格式,那麼怎麼轉呢?



以下來看看吧!

前言

 


 

之前因為實驗室學妹要當助教的關係,希望透過CLR來寫視窗介面,並希望能夠把OpenCV影像格式可以顯示在視窗的PictureBox上,而不是使用OpenCV內建的imshow

而這時候我們便要把OpenCV的影像格式轉換成PictureBox吃的格式,那麼怎麼轉呢?

 

以下來看看吧!

 

轉換格式

 


 

我們要轉換的格式是bitmap,以把圖像指定到PicutreBox的image屬性,所以這邊用了一個Fuction來做格式轉換,回傳的是bitmap

1.首先我們先確認通道是單通道還是三通道:


if (img->depth == 8)
{
                if (img->nChannels == 3) //iplImage為BGR格式
                { 
                }
                else if(img->nChannels ==1) //iplImage為灰階格式
                { 
                }
}

 

2.如果是三通道,則初始化並回傳bitmap物件


return gcnew System::Drawing::Bitmap(img->width , img->height , img->widthStep , System::Drawing::Imaging::PixelFormat::Format24bppRgb , (System::IntPtr)img->imageData);

 

3.如果是單通道:

由於bitmap的pxelFormat中沒有剛好是8bit Gray的格式,所以我們只好使用三通道來替代

 


//為了符合Bitmap格式Format24bppRgb,解決方法之一為將單通道轉為3通道,變成BGR的格式。
int step       = img->widthStep;
uchar* oData    = (uchar*)img->imageData;

//創建一個三通道的iplimage,裡面存放的是原先單通道的灰階圖

IplImage* nImg = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,3);
int nStep       = nImg->widthStep;
int nChannels   = nImg->nChannels;
uchar* nData    = (uchar *)nImg->imageData;
for (int j = 0; j height; j++)
{
                        for (int i = 0; i width; i++)
                        {
                            int counter = j*nStep + i*nChannels;
                            nData[counter+ 0] = oData[j*step + i];
                            nData[counter+ 1] = oData[j*step + i];
                            nData[counter+ 2] = oData[j*step + i];
                        }
}

//轉換成bitmap回傳
return gcnew System::Drawing::Bitmap(nImg->width , nImg->height , nImg->widthStep , System::Drawing::Imaging::PixelFormat::Format24bppRgb, (System::IntPtr)nImg->imageData);

 

全部程式碼

 




private: System::Drawing::Bitmap^  iplImageToBitmap(IplImage *img)
         {
            if (img->depth == 8)
            {
                if (img->nChannels == 3) //iplImage為BGR格式
                {
                    return gcnew System::Drawing::Bitmap(img->width , img->height , img->widthStep , System::Drawing::Imaging::PixelFormat::Format24bppRgb , (System::IntPtr)img->imageData);
                }
                else if(img->nChannels ==1) //iplImage為灰階格式
                {
                    //為了符合Bitmap格式Format24bppRgb,解決方法之一為將單通道轉為3通道,變成BGR的格式。
                    int step       = img->widthStep;
                    uchar* oData    = (uchar*)img->imageData;

                    IplImage* nImg = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,3);
                    int nStep       = nImg->widthStep;
                    int nChannels   = nImg->nChannels;
                    uchar* nData    = (uchar *)nImg->imageData;
                    for (int j = 0; j height; j++)
                    {
                        for (int i = 0; i width; i++)
                        {
                            int counter = j*nStep + i*nChannels;
                            nData[counter+ 0] = oData[j*step + i];
                            nData[counter+ 1] = oData[j*step + i];
                            nData[counter+ 2] = oData[j*step + i];
                        }
                    }
                    return gcnew System::Drawing::Bitmap(nImg->width , nImg->height , nImg->widthStep , System::Drawing::Imaging::PixelFormat::Format24bppRgb, (System::IntPtr)nImg->imageData);
                }
            }
        }

 

 

最近剛好也有朋友遇到這個問題,所以便想,應該可以把文章記錄下來,以方便其他有需要的人可以快速解決 =)

 


 

文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)

另外要轉載請附上出處 感謝