MFC动态绘图+OpenCV画图

本程序运用到了OpenCv库,采用2.47版本。、

本程序中也充分运用到了MFC框架下的两个坐标系:屏幕坐标系和客户区坐标系。

本程序利用MFC画图技术+OpenCv技术实现功能:

1、通过文件对话框,利用OpenCv将图片加载并刷新到MFC Picture控件上。

根据OpenCv载入图片数据得到MFC BitMapInfo 位图信息。

LPBITMAPINFO CDrawAndOpenCVDlg::CtreateMapInfo(IplImage* workImg)
{
    BITMAPINFOHEADER BIH={40,1,1,1,8,0,0,0,0,0,0};
    LPBITMAPINFO lpBmi;
    int          wid, hei, bits, colors,i;
    RGBQUAD  ColorTab[256];
    wid =workImg->width;   
    //正负不对将导致图片颠倒
    hei =(workImg->origin == 0) ? -workImg->height:workImg->height; 
    bits=workImg->depth*workImg->nChannels;
    if (bits>8) colors=0;
    else colors = 1<<bits;

    int nsize = sizeof(BITMAPINFO);
    lpBmi=(LPBITMAPINFO) malloc(40+4*colors);
    BIH.biWidth   =wid;     BIH.biHeight  =hei;
    BIH.biBitCount=(BYTE) bits;
    memcpy(&lpBmi->bmiHeader, &BIH, 40);    //  复制位图信息头 
    if (bits==8) {                          //  256 色位图
        for (i=0;i<256;i++)  {              //  设置灰阶调色板
            ColorTab[i].rgbRed=ColorTab[i].rgbGreen=ColorTab[i].rgbBlue=(BYTE) i;
        }
        memcpy(lpBmi->bmiColors, ColorTab, 1024);
    }
    return(lpBmi);
}

利用OpenCv载入图片并将其显示到Picture控件上,其中img为IplImage*,已经载入。

BOOL CDrawAndOpenCVDlg::displayImage()
{
    CDC* pDC = mPictureStatic.GetDC();
    CRect rect;
    mPictureStatic.GetClientRect(rect);
    HDC hDC = pDC->GetSafeHdc();
    LPBITMAPINFO bitmap = CtreateMapInfo(img);
    ::SetStretchBltMode (hDC, STRETCH_DELETESCANS);
    ::StretchDIBits(hDC , rect.left , rect.top ,  rect.Width() , rect.Height(),
        0 , 0 , img->width , img->height,  img->imageData , 
        bitmap,DIB_RGB_COLORS,SRCCOPY);
    ReleaseDC(pDC);
    pDC = NULL;
    delete bitmap;
    bitmap = NULL;
    return TRUE;
}

2、实现对Picture控件进行动态画图,本实时加载到图片数据上进行显示。
动态绘图主要处理三个鼠标消息响应:

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);

在OnMouseMove中主要处理:

CPoint p1 = mPoint1;
            CPoint p2 = mPoint2;
            CDC *pDC = mPictureStatic.GetDC();
            pDC->SetROP2(R2_XORPEN); //这是关键,先去反色
            pDC->SelectObject(mMFCPen);
            CBrush *newBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
            pDC->SelectObject(newBrush);
            switch(drawType) {
            case 1:  //画线
                {               
                    pDC->MoveTo(p1);
                    pDC->LineTo(p2); //将上次画的线反色再画
                    p2 = mPoint2 = point;
                    pDC->MoveTo(p1);
                    pDC->LineTo(p2); //画本次线
                    ReleaseDC(pDC);
                    break;
                }
            case 2:
                {           
                    CRect rect(p1, p2);
                    pDC->Rectangle(rect);
                    p2 = mPoint2 = point;
                    if(p1.x > p2.x){
                        long x = p1.x;
                        p1.x = p2.x;
                        p2.x = x;
                    }
                    if(p1.y > p2.y){
                        long y = p1.y;
                        p1.y = p2.y;
                        p2.y = y;
                    }
                    rect.SetRect(p1, p2);
                    pDC->Rectangle(rect);
                    break;
                }

            }
            newBrush->DeleteObject();
            ReleaseDC(pDC);

OpenCv绘图主要有两个函数:

void CDrawAndOpenCVDlg::drawLineToImage()
{
    CRect rect;
    mPictureStatic.GetClientRect(rect);
    CvPoint cvPo1, cvPo2;
    cvPo1.x = mPoint1.x * img->width / rect.Width();
    cvPo1.y = mPoint1.y * img->height / rect.Height();
    cvPo2.x = mPoint2.x * img->width / rect.Width();
    cvPo2.y = mPoint2.y * img->height / rect.Height();
    int tempWidth = lineWidth * img->width / rect.Width();
    cvLine(img, cvPo1, cvPo2, mCvScaler, tempWidth);
    displayImage();
}
void CDrawAndOpenCVDlg::drawRectToImage()
{
    if(mPoint1.x > mPoint2.x){
        long x = mPoint1.x;
        mPoint1.x = mPoint2.x;
        mPoint2.x = x;
    }
    if(mPoint1.y > mPoint2.y){
        long y = mPoint1.y;
        mPoint1.y = mPoint2.y;
        mPoint2.y = y;
    }
    CRect rectPicStatic;
    CvPoint cvPo1, cvPo2;
    mPictureStatic.GetClientRect(rectPicStatic);
    cvPo1.x = mPoint1.x * img->width / rectPicStatic.Width();
    cvPo1.y = mPoint1.y * img->height / rectPicStatic.Height();
    cvPo2.x = mPoint2.x * img->width / rectPicStatic.Width();
    cvPo2.y = mPoint2.y * img->height / rectPicStatic.Height();
    int tempWidth = lineWidth * img->width / rectPicStatic.Width();
    cvRectangle(img, cvPo1, cvPo2, mCvScaler, tempWidth);
    displayImage();
}

3、可实现对画图颜色和线宽的选择,画图方式有矩形和线。颜色选择主要在void OnLButtonDown(UINT nFlags, CPoint point);中处理:

    ClientToScreen(&point); //将对话框客户区坐标point转换为屏幕坐标
    CRect rect;
    mColourStatic.GetWindowRect(rect); //得到屏幕坐标系下的mColourStatic矩形坐标
    if(rect.PtInRect(point)){
        CColorDialog m_setClrDlg;
        // CC_RGBINIT可以让上次选择的颜色作为初始颜色显示出来
        m_setClrDlg.m_cc.Flags |= CC_FULLOPEN|CC_RGBINIT;   
        m_setClrDlg.m_cc.rgbResult = mMFCColor; //记录上次选择的颜色
        if(IDOK ==m_setClrDlg.DoModal())
            mMFCColor = m_setClrDlg.m_cc.rgbResult; // 保存用户选择的颜色    
        fillColourStatic();
        mMFCPen.DeleteObject();
        mCvScaler.val[0] = GetBValue(mMFCColor);
        mCvScaler.val[1] = GetGValue(mMFCColor);
        mCvScaler.val[2] = GetRValue(mMFCColor);
        lineWidth = mLineWidthBox.GetCurLineWidth();
        mMFCPen.CreatePen(PS_SOLID, lineWidth, 
            RGB(GetRValue(mMFCColor), GetGValue(mMFCColor), GetBValue(mMFCColor)));
    }

4、可将最终画的图片进行本地保存,在画图过程还可以进行还原,全部删除前面所画图形。
下载地址:http://download.csdn.net/detail/qq_20828983/9609281
程序效果:

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

### 回答1: MFC(Microsoft Foundation Classes)是Microsoft公司开发的一个用于Windows应用程序开发的C++类库。它提供了一个图形用户界面(GUI)框架,使开发人员可以创建Windows应用程序。OpenCV(Open Source Computer Vision)是一个开源的计算机视觉库,它支持各种图像处理和计算机视觉算法,包括图像处理、高级计算机视觉、机器学习、目标检测和跟踪等。 MFCOpenCV可以一起使用来开发Windows图像处理应用程序。MFC提供了图形界面,可以让用户与程序进行交互;而OpenCV提供了强大的图像处理和计算机视觉功能,可以对图像进行分析和处理。使用MFCOpenCV结合起来可以让开发人员轻松地创建一个功能强大的图像处理程序。 在使用MFCOpenCV开发图像处理应用程序时,开发人员需要熟悉MFCOpenCV的相关知识,掌握MFC的Windows编程和OpenCV的图像处理能力。开发人员可以使用MFC的窗口、对话框和控件等创建图形界面,然后使用OpenCV来进行图像的读取、处理和输出等操作。开发人员需要在开发过程中注意MFCOpenCV的相互调用关系,使得程序可以正确运行。 总之,MFCOpenCV是两个强大的工具,它们可以一起使用来开发图像处理应用程序。在使用MFCOpenCV开发图像处理应用程序时,开发人员需要熟悉它们的相关知识并合理地运用它们的功能,才能开发出高效、易用、功能强大的应用程序。 ### 回答2: MFC是Microsoft Foundation Class的缩写,是Windows操作系统上的一个GUI应用程序框架,可以帮助开发者快速地创建窗口和用户界面。而OpenCV是一个流行的开源计算机视觉库,可以用于图像处理、模式识别、物体跟踪等方面。由于MFCOpenCV都是针对Windows系统的开发,因此结合使用这两个工具可以方便地实现图像处理和GUI设计的功能。 通过MFC,开发者可以创建一个具有图形界面的应用程序,然后与OpenCV结合可以实现图像处理的各种功能,例如图像滤波,图像分割,特征提取等。通过这种方法,开发者可以快速且方便地开发出图像处理软件,而且可以为MFC界面添加很多可以增强用户体验的控件。 举个例子,假设我们要设计一个用于人脸识别的软件,我们可以使用MFC创建一个简单的用户界面,然后通过OpenCV提供的人脸检测算法来实现人脸识别功能。在这个软件中,OpenCV将负责图像处理和人脸检测部分,而MFC将负责用户界面的设计和数据的输入输出。 总之,MFCOpenCV的结合可以为Windows下的图像处理软件开发提供很大的便利,可以满足很多应用程序的需求。 ### 回答3: MFC是Microsoft Foundation Class的缩写,是微软公司针对Windows操作系统开发的应用程序框架。它提供了许多可重用的类,用于简化Windows应用程序的开发过程。而OpenCV是一种开源计算机视觉库,提供了许多图像处理和计算机视觉算法及工具,可以用于实现包括人脸检测、图像识别等多种应用。它的优势在于它的代码简洁易懂,易于学习,同时也提供了Python、C++等多种编程语言的接口。 使用MFCOpenCV4相结合可以实现很多图像处理的应用,比如图像的读入、载入、预处理、显示等等,可以非常方便的实现对图像的各种操作。另外,MFC框架可以提供一些Windows操作系统的API,用于支持与系统交互的功能,比如打开选择文件框、保存文件框等等。结合OpenCVMFC的图像处理应用可以方便的实现这些操作和一些自定义的交互界面。 总之,MFCOpenCV4的结合可以方便、高效的实现计算机视觉领域的图像处理应用程序,为人工智能和机器视觉等领域提供了很好的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值