之前因為實驗室學妹要當助教的關係,希望透過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);
}
}
}
最近剛好也有朋友遇到這個問題,所以便想,應該可以把文章記錄下來,以方便其他有需要的人可以快速解決 =)
文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)
另外要轉載請附上出處 感謝