2012-05-31 10 views
0

У меня есть приложение для камеры с использованием opencv, где я использую MFC GUI. Мне нужно преобразовать CImage в IplImage для модулей Opencv для обработки изображений и преобразовать его обратно в CImage для отображения в окно снова.Преобразование из MFC CImage в Opencv IPlImage

Я исследовал в этой теме, но не достаточно примеров и solutions.Anybody есть suggestions.Thanks

Это мой код ...

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

ты имел взгляд на определение класса CImage? Вы взглянули на определение структуры IplImage? Вы видите некоторые шаблоны? – alinoz

ответ

1

Если бы эта проблема долгое время себя. Я нашел этот код here, который я закончил тем, что работал хорошо. Вместо того, чтобы исследовать "CImage к 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

Если растровое изображение на вид, вы можете использовать устройство контекст (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); 
0

Я искал половину ночи за утечку памяти для копирования и вставки и, наконец, нашел ее!

Так вот обновленный фрагмент кода оригинального ответа. Главное для меня, чтобы использовать cvCreateImage вместо cvCreateImageHeader потому, что я использовал cvReleaseImage после вызова hBitmap2IplImage. В моем случае также нужно было листать. Ура!

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 
Смежные вопросы