我正在使用opencv的相机应用程序,我正在使用MFC GUI。我需要将CImage转换为IplImage用于Opencv模块以进行图像处理,并将其转换回CImage以便再次在窗口中显示。
我研究了这个主题,但没有足够的例子和解决方案。任何人都有一些建议。谢谢
这是我的代码......
void CChildView::OnFileOpenimage(void)
{
// TODO: Add your command handler code here
CString strFilter;
CSimpleArray<GUID> aguidFileTypes;
HRESULT hResult;
hResult = imgOriginal.GetExporterFilterString(strFilter,aguidFileTypes);
if (FAILED(hResult)) {
CString fmt;
fmt.Format("GetExporterFilter failed:\n%x - %s", hResult, _com_error(hResult).ErrorMessage());
::AfxMessageBox(fmt);
return;
}
CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST, strFilter);
dlg.m_ofn.nFilterIndex = m_nFilterLoad;
hResult = (int)dlg.DoModal();
if(FAILED(hResult)) {
return;
}
m_nFilterLoad = dlg.m_ofn.nFilterIndex;
imgOriginal.Destroy();
CString pathval = dlg.GetPathName();
hResult = imgOriginal.Load(dlg.GetPathName());
if (FAILED(hResult)) {
CString fmt;
fmt.Format("Load image failed:\n%x - %s", hResult, _com_error(hResult).ErrorMessage());
::AfxMessageBox(fmt);
return;
}
// IplImage *img from imgOriginal; want to convert here for further processing.
m_nImageSize = SIZE_ORIGINAL;
Invalidate();
UpdateWindow();
}
答案 0 :(得分:1)
这个问题已经有一段时间了。我找到了这个代码here,我最终使用它,效果很好。而不是研究“CImage to IplImage”,你应该搜索“HBITMAP到IplImage”
IplImage* hBitmap2Ipl(HBITMAP hBmp, bool flip)
{
BITMAP bmp;
::GetObject(hBmp,sizeof(BITMAP),&bmp);
int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel/8;
int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
IplImage *img=cvCreateImageHeader(cvSize(bmp.bmWidth, bmp.bmHeight), depth, nChannels);
img->imageData = (char*)malloc(bmp.bmHeight*bmp.bmWidth*nChannels*sizeof(char));
memcpy(img->imageData,(char*)(bmp.bmBits),bmp.bmHeight*bmp.bmWidth*nChannels);
return img;
}
用法:
ATL::CImage image;
//whatever code you use to generate the image goes here
IplImage *convertedImage=hBitmap2Ipl(image.Detach());
image.Destroy();
答案 1 :(得分:0)
我半夜搜索了我的复制粘贴内存泄漏,最后找到了它!
所以这是原始答案的更新代码段。对我来说重要的是使用 cvCreateImage 而不是 cvCreateImageHeader ,因为在调用 hBitmap2IplImage 之后我确实使用了 cvReleaseImage 。在我的案例中也需要翻转。干杯!
IplImage* hBitmap2IplImage(HBITMAP hBmp, bool flip)
{
BITMAP bmp;
::GetObject(hBmp,sizeof(BITMAP),&bmp);
int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel/8;
int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
IplImage *img=cvCreateImage(cvSize(bmp.bmWidth, bmp.bmHeight), depth, nChannels);
size_t imgSize = bmp.bmHeight*bmp.bmWidth*nChannels;
memcpy_s(img->imageData, imgSize, (char*)(bmp.bmBits), imgSize);
if (flip)
cvFlip(img, NULL, 0);
return img;
}
用法:
ATL::CImage image;
HBITMAP hBitmap = image.Detach(); // some handle to your bitmap
bool flip = true;
IplImage* pSomeIplImage = hBitmap2IplImage(hBitmap, flip);
image.Destroy();
//
// use "pSomeIplImage"
//
cvReleaseImage( &pSomeIplImage ); // don't forget
答案 2 :(得分:-1)
如果位图图像在视图上,您可以使用设备上下文(CDC dcBuffer)进行复制。
IplImage *pCapture = cvCreateImage(cvSize(U16_IMAGE_WIDTH/2,U16_IMAGE_HEIGHT/2),8, 3);
::GetDIBits(dcBuffer.GetSafeHdc(), bitmapBuffer, 0, U16_IMAGE_HEIGHT/2, pCapture->imageData, &bitmapInfo, DIB_RGB_COLORS);
cvSaveImage("temp.bmp", pCapture);
cvReleaseImage(&pCapture);