下面内容选自OpenCV中文论坛
1.轮廓上的点如何获得?
我在二值图像中用cvFindContours找到了物体的轮廓,如何获取轮廓上的点的坐标?小弟是新手,请大家告知。
可以用:cvCvtSeqToArray
2.在较为简单的背景中怎么把手直接分离出来啊?
如果真的是背景比较简单的话 肤色可以 效果也不错
3.如何在MFC框架内显示图片,并支持鼠标回调函数?
现在显示时,都是弹出一个新窗口,我想让它在框架内显示,而且还可以支持鼠标回调函数?请高手帮忙呀!
把IplImage看作普通的图像, 将该图像绘制到MFC中的DC就可以显示了. 至于鼠标回调是MFC的责任, 和OpenCV没有任何关系. 绘制IplImage到DC的代码请参考: http://opencv-extension-library.googlec ... CvxWin32.h http://opencv-extension-library.googlec ... xWin32.cpp MFC+OpenCV实现的一个图像浏览工具: http://opencv-extension-library.googlec ... ample/mfc/ 不过CvxLib可能已经不是最新的了, 不知道能不能用. 绘制在OnDraw函数实现:
代码: 全选
void CCvxLibAppView::OnDraw(CDC * pDC)
... {
CCvxLibAppDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// 绘制到DC
CvxWin32::DrawToHDC(m_viewer.getViewer(), pDC->GetSafeHdc(), NULL);
}
我是想利用OpenCV提供的那个on_mouse回调函数。我现在是按照例程做的,可是总需要弹出一个窗口。
只适用on_mouse的话就和MFC没有关系了, on_mouse的使用技巧请参考CvxWindow类的实现: http://opencv-extension-library.googlec ... vxWindow.h http://opencv-extension-library.googlec ... Window.cpp 不过目前的CvxWindow代码还有问题, 你下载以前的代码看看吧. http://www.opencv.org.cn/images/e/e9/CvxLib-code.zip
4.如何在MFC中将IplImage转换成DIB并显示(转自Yahoo Group)?
----Convert IplImage to Device Independent Bitmap (aka DIB)
This is the code i used in my project, you can adapt it for your application, keep in mind there are several features/variables u might wan to remove (ie the ROI rect drawing)
HBITMAP CXMLDlg::CreateBitmap(int w,int h,WORD bpp,int Size) { HDC hDC = ::CreateCompatibleDC(0); BYTE tmp[sizeof(BITMAPINFO)+255*4]; BITMAPINFO *bmi = (BITMAPINFO*)tmp; HBITMAP hBmp; int i; memset(bmi,0,sizeof(BITMAPINFO)); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi->bmiHeader.biWidth = w; bmi->bmiHeader.biHeight = h; bmi->bmiHeader.biPlanes = Size; bmi->bmiHeader.biBitCount = bpp; bmi->bmiHeader.biCompression = BI_RGB; bmi->bmiHeader.biSizeImage = w*h*1; bmi->bmiHeader.biClrImportant =0 ; switch(bpp) { case 8 : for(i=0 ; i < 256 ; i++) { bmi->bmiColors[i].rgbBlue = i; bmi->bmiColors[i].rgbGreen= i; bmi->bmiColors[i].rgbRed= i; } break; case 32: case 24: ((DWORD*) bmi->bmiColors)[0] = 0x00FF0000; /* red mask */ ((DWORD*) bmi->bmiColors)[1] = 0x0000FF00; /* green mask */ ((DWORD*) bmi->bmiColors)[2] = 0x000000FF; /* blue mask */ break; } hBmp = ::CreateDIBSection(hDC,bmi,DIB_RGB_COLORS,NULL,0,0); ::DeleteDC(hDC); return hBmp; } int CXMLDlg::ChangePreview(IplImage* img) { if(m_bmp) //if bitmap allocated before { //release previous bitmap ::DeleteObject(m_bmp); } m_bmp = CreateBitmap(img->width,img->height,img->nChannels * img->depth,1); SetBitmapBits(m_bmp,img->imageSize,img->imageData); int h,w; RECT r; GetDlgItem(IDC_SHOW)->GetWindowRect(&r); //ScreenToClient(&r); w = r.right - r.left; h = r.bottom - r.top; if (w < h) m_fScaleRatio =(double) w / img->width; else if (w >= h) m_fScaleRatio =(double) h / img->height; return 1; } void CXMLDlg::OnPaint() { CPaintDC dc(this); // device context for local painting // TODO: Add your message handler code here if (!m_bmp) return; BITMAP bmp; RECT r; CDC tmp; int w,h; GetDlgItem(IDC_SHOW)->GetWindowRect(&r); ScreenToClient(&r); tmp.CreateCompatibleDC(0); CBitmap *old = tmp.SelectObject(CBitmap::FromHandle(m_bmp)); ::GetObject(m_bmp,sizeof(BITMAP),&bmp); w = r.right - r.left; h = r.bottom - r.top; /* Make sure to use the stretching mode best for color pictures */ dc.SetStretchBltMode(COLORONCOLOR); //dc->StretchBlt(r.left,r.top,w,h,&tmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); dc.StretchBlt(9,9,(int)(bmp.bmWidth * m_fScaleRatio)-1, (int)(bmp.bmHeight * m_fScaleRatio)-1,&tmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); tmp.SelectObject(old); CGdiClass::DrawRect(&dc,m_rcROI,RGB(0,255,0)); // Do not call CDialogBar::OnPaint() for painting messages }