首页 > 代码库 > OpenCV常用图像操作和鼠标操作(双11版本)

OpenCV常用图像操作和鼠标操作(双11版本)

更新日志:

1.添加了自适应窗口大小的功能;

2.添加了在图像上画矩形的功能;

3.添加了在大图上画矩形的功能;

4.部分函数名称更改;

5其他修改。

 

首先是头文件:

/* ******* ccv.h ******************* opencv常用操作函数声明 ********** *//* author: autumoon */#ifndef _CCV_H_#define _CCV_H_#include <afxdlgs.h> //打开文件#include "cv.h"#include "cxcore.h"#include "highgui.h"  using namespace cv;#define SCREEN_WIDTH     1920#define SCREEN_HEIGHT    1080class CCvImage{public:    Mat m_Minput; //使用Mat类型    //鼠标控制相关变量    Mat m_Mmask;    Mat m_Mmid;    Mat m_Msrc; //外部矩阵输入    char* m_szTitle;    CvPoint m_curr_pt;    CvPoint m_prev_pt;    CvRect m_rect;    CvRect m_CRroi;    float m_fProportion;    int m_nThick;public:    CCvImage();    CCvImage(Mat mat);    CCvImage(IplImage* pImage);    CCvImage(char szImgPath[], int flags = 1);    CCvImage(CString strImgPath, int flags = 1);public:    //图像操作    int AdaptiveFindThreshold(CvMat *dx, CvMat *dy, double *low, double *high);    int AutoSizeMat(Mat& Msrc, Mat& Mdst, float& fProportion, int nScreenWidth = SCREEN_WIDTH, int nScreenHeight = SCREEN_HEIGHT);    int CannyAutoThreshold(Mat Msrc, Mat& Mdst);    int EasyCanny(Mat Msrc, Mat& Mdst, double threshold1 = 100, double threshold2 = 200);    int ErodeDilate(Mat Msrc, Mat& Mdst, int nPos); //nPos < 10 腐蚀,nPos > 10 膨胀    int OpenClose(Mat Msrc, Mat& Mdst, int nPos); //nPos < 10 开运算,nPos > 10 闭运算    int ShowImg(char szTitle[] = "显示图像", bool bAutoClose = true);    int ShowImg(Mat Msrc, char szTitle[] = "显示图像", bool bAutoClose = true); //显示某个矩阵    int ShowImgAutoSize(char szTitle[] = "显示图像", int nScreenWidth = SCREEN_WIDTH, int nScreenHeight = SCREEN_HEIGHT,  bool bAutoClose = true);    int ShowImgAutoSize(Mat Msrc, char szTitle[] = "显示图像", int nScreenWidth = SCREEN_WIDTH, int nScreenHeight = SCREEN_HEIGHT,  bool bAutoClose = true);    int SobelCalc(Mat Msrc, Mat& pMdst, bool bGray = false);    //鼠标图像操作    int DrawCurveOnImg(Mat Msrc, char* szTitle = "画曲线", int nThick = 2);    int DrawCurveOnBigImg(Mat Msrc, int nScreenWidth = SCREEN_WIDTH, int nScreenHeight = SCREEN_HEIGHT, char* szTitle = "画曲线", int nThick = 2);    int DrawLineOnImg(Mat Msrc, CvPoint& pStart, CvPoint& pEnd, char* szTitle = "画直线", int nThick = 2);    int DrawLineOnBigImg(Mat Msrc, CvPoint& pStart, CvPoint& pEnd, int nScreenWidth = SCREEN_WIDTH, int nScreenHeight = SCREEN_HEIGHT, char* szTitle = "画直线", int nThick = 2);    int DrawRectOnImg(Mat Msrc, CvRect& rect, char* szTitle = "画矩形", int nThick = 2);    int DrawRectOnBigImg(Mat Msrc, CvRect& rect, int nScreenWidth = SCREEN_WIDTH, int nScreenHeight = SCREEN_HEIGHT, char* szTitle = "画矩形", int nThick = 2);    int GetMaskByCurve(Mat Msrc, Mat& pDst, char* szTitle = "获取遮罩"); //通过曲线获取遮罩    int GetMaskByDaub(Mat Msrc, Mat& pDst, int nRadius = 20, char* szTitle = "获取遮罩"); //通过涂抹获取遮罩    //其他操作    int ResetRect(CvRect& rect, int nValue = http://www.mamicode.com/-1);    int ResizePoint(CvPoint& Csrc, float fProportion);    int ResizeRect(CvRect& Csrc, float fProportion);    int ResizeRect(CvRect& rect, int nExpandWidthPixs = 0, int nExpandHeightPixs = 0);    int ResizeRect(CvRect& rect, int nLeft, int nRight, int nUp, int nDown);    int ValidExpandValue(const CvRect& CRroi, int& nLeft, int& nRight, int& nUp, int& nDown, int nWidth, int nHeight);    int ValidRect(CvRect& rect, const int nWidth, const int nHeight);    int ValidRect(CvRect& rectSmall, const int nRectWidth, const int nRectHeight, const int nPicWidth, const int nPicHeight);private:    IplImage* IInput; //内部使用的IplImage指针};//回调函数void on_mouse_curve(int event, int x, int y, int flags, void* pParameters);void on_mouse_big_curve(int event, int x, int y, int flags, void* pParameters);void on_mouse_curve_mask(int event, int x, int y, int flags, void* pParameters);void on_mouse_daub(int event, int x, int y, int flags, void* pParameters);void on_mouse_line(int event, int x, int y, int flags, void* pParameters);void on_mouse_rect(int event, int x, int y, int flags, void* pParameters);#endif

 

然后是cpp文件:

/* ******* ccv.cpp ******************* opencv常用操作函数实现 ********** *//* author: autumoon */#include "ccv.h"CCvImage::CCvImage(){    ResetRect(m_rect);    ResetRect(m_CRroi);    IInput = NULL;}CCvImage::CCvImage(char szImgPath[], int flags/* = 1*/){    ResetRect(m_rect);    ResetRect(m_CRroi);    IInput = NULL;    m_Minput = imread(szImgPath, flags);}CCvImage::CCvImage(CString strImgPath, int flags/* = 1*/){    ResetRect(m_rect);    ResetRect(m_CRroi);    IInput = NULL;    char* szImgPath;#ifdef _UNICODE    USES_CONVERSION;    szImgPath = W2A(strCstring);#else    szImgPath = (LPSTR)(LPCTSTR)strImgPath;#endif    m_Minput = imread(szImgPath, flags);}int CCvImage::AdaptiveFindThreshold(CvMat *dx, CvMat *dy, double *low, double *high){                                                                                  CvSize size;                                                               IplImage *imge=0;                                                          int i,j;                                                                   CvHistogram *hist;                                                         int hist_size = 255;                                                       float range_0[]={0,256};                                                   float* ranges[] = { range_0 };                                             double PercentOfPixelsNotEdges = 0.7;                                      size = cvGetSize(dx);                                                      imge = cvCreateImage(size, IPL_DEPTH_32F, 1);                              // 计算边缘的强度, 并存于图像中                                            float maxv = 0;                                                            for(i = 0; i < size.height; i++ )                                          {                                                                              const short* _dx = (short*)(dx->data.ptr + dx->step*i);                const short* _dy = (short*)(dy->data.ptr + dy->step*i);                float* _image = (float *)(imge->imageData + imge->widthStep*i);        for(j = 0; j < size.width; j++)                                        {                                                                          _image[j] = (float)(abs(_dx[j]) + abs(_dy[j]));                    maxv = maxv < _image[j] ? _image[j]: maxv;                     }                                                                  }                                                                          if(maxv == 0){                                                                 *high = 0;                                                             *low = 0;                                                              cvReleaseImage( &imge );                                               return -1;                                                            }                                                                          // 计算直方图                                                              range_0[1] = maxv;                                                         hist_size = (int)(hist_size > maxv ? maxv:hist_size);                      hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);              cvCalcHist( &imge, hist, 0, NULL );                                        int total = (int)(size.height * size.width * PercentOfPixelsNotEdges);     float sum=0;                                                               int icount = hist->mat.dim[0].size;                                        float *h = (float*)cvPtr1D( hist->bins, 0 );                               for(i = 0; i < icount; i++)                                                {                                                                              sum += h[i];                                                           if( sum > total )                                                          break;                                                     }                                                                          // 计算高低门限                                                            *high = (i+1) * maxv / hist_size ;                                         *low = *high * 0.4;                                                        cvReleaseImage( &imge );                                                   cvReleaseHist(&hist);    return 0;}    int CCvImage::AutoSizeMat(Mat& Msrc, Mat& Mdst, float& fProportion, int nScreenWidth/* = SCREEN_WIDTH*/, int nScreenHeight/* = SCREEN_HEIGHT*/){    if (Msrc.cols <= nScreenWidth && Msrc.rows <= nScreenHeight)    {        Msrc.copyTo(Mdst);        fProportion = 1.0;        return 0;    }    if ((float)Msrc.cols / Msrc.rows >= (float)nScreenWidth / nScreenWidth)    {        fProportion = (float)Msrc.cols / nScreenWidth;    }    else    {        fProportion = (float)Msrc.rows / nScreenHeight;    }    resize(Msrc, Mdst, cv::Size(Msrc.cols / fProportion, Msrc.rows / fProportion));    return 0;}int CCvImage::CannyAutoThreshold(Mat Msrc, Mat& Mdst){    double low, high;    IplImage Isrc = Msrc;    Mat src;    if (Msrc.channels() == 3)    {        cvtColor(Msrc, src, CV_RGB2GRAY);    }    else    {        src = Msrc;    }    const int cn = src.channels();                                             Mat dx(src.rows, src.cols, CV_16SC(cn), BORDER_REPLICATE);                               Mat dy(src.rows, src.cols, CV_16SC(cn), BORDER_REPLICATE);                               Sobel(src, dx, CV_16S, 1, 0, 3, 1, 0);    Sobel(src, dy, CV_16S, 0, 1, 3, 1, 0);    CvMat _dx = dx, _dy = dy;                                                  AdaptiveFindThreshold(&_dx, &_dy, &low, &high);    Canny(Msrc, Mdst, low, high);    return 0;}int CCvImage::EasyCanny(Mat Msrc, Mat& Mdst, double threshold1/* = 100*/, double threshold2/* = 200*/){    Mat Mgray;    if (Msrc.channels() == 3)    {        cvtColor(Msrc, Mgray, CV_RGB2GRAY);    }    else    {        Mgray = Msrc;    }    Canny(Mgray, Mdst, threshold1, threshold2);    return 0;}int CCvImage::ErodeDilate(Mat Msrc, Mat& Mdst, int nPos){    int n = nPos - 10;    int an = n > 0 ? n : -n;    Mat element = getStructuringElement(MORPH_RECT, Size(an*2+1, an*2+1), Point(an, an) );    if( n < 0 )        erode(Msrc, Mdst, element);    else        dilate(Msrc, Mdst, element);    return 0;}int CCvImage::OpenClose(Mat Msrc, Mat& Mdst, int nPos){    int n = nPos - 10;    int an = n > 0 ? n : -n;    Mat element = getStructuringElement(MORPH_RECT, Size(an*2+1, an*2+1), Point(an, an) );    if( n < 0 )        morphologyEx(Msrc, Mdst, CV_MOP_OPEN, element);    else        morphologyEx(Msrc, Mdst, CV_MOP_CLOSE, element);    return 0;}int CCvImage::ShowImg(char szTitle[]/* = "显示图像"*/, bool bAutoClose/* = true*/){    imshow(szTitle, m_Minput);    waitKey();    if (bAutoClose)    {        destroyWindow(szTitle);    }    return 0;}int CCvImage::ShowImg(Mat Msrc, char szTitle[]/* = "显示图像"*/, bool bAutoClose/* = true*/){    imshow(szTitle, Msrc);    waitKey();    if (bAutoClose)    {        destroyWindow(szTitle);    }    return 0;}int CCvImage::ShowImgAutoSize(char szTitle[]/* = "显示图像"*/, int nScreenWidth/* = 1920*/, int nScreenHeight/* = 1080*/, bool bAutoClose/* = true*/){    return ShowImgAutoSize(m_Minput, szTitle, nScreenWidth, nScreenHeight, bAutoClose);}int CCvImage::ShowImgAutoSize(Mat Msrc, char szTitle[]/* = "显示图像"*/, int nScreenWidth/* = 1920*/, int nScreenHeight/* = 1080*/, bool bAutoClose/* = true*/){    Mat Mresize;    float fProportion;    AutoSizeMat(Msrc, Mresize, fProportion, nScreenWidth, nScreenHeight);    imshow(szTitle, Mresize);    waitKey();    if (bAutoClose)    {        destroyWindow(szTitle);    }    return 0;}int CCvImage::SobelCalc(Mat Msrc, Mat& pMdst, bool bGray/* = false*/){        Mat src, dst_x, dst_y, dst;    if (bGray && Msrc.channels() == 3)    {        cvtColor(Msrc, src, CV_RGB2GRAY);    }    else    {        src = Msrc;    }    Sobel(src, dst_x, src.depth(), 1, 0);      Sobel(src, dst_y, src.depth(), 0, 1);      convertScaleAbs(dst_x, dst_x);      convertScaleAbs(dst_y, dst_y);      addWeighted( dst_x, 0.5, dst_y, 0.5, 0, dst);    dst.copyTo(pMdst);    return 0;  }int CCvImage::DrawCurveOnImg(Mat Msrc, char* szTitle/* = "画曲线"*/, int nThick/* = 2*/){    m_Mmid.release();    m_Mmid = Msrc;    //显示原图    imshow(szTitle,m_Mmid);    //鼠标回调函数    this->m_szTitle = szTitle;    this->m_nThick = nThick;    cvSetMouseCallback(szTitle, on_mouse_curve, this);    waitKey(0);    destroyWindow(szTitle);    return 0;}void on_mouse_curve(int event, int x, int y, int flags, void* pParameters){    CCvImage* pthis = (CCvImage*)pParameters;    //获取相关的参数    char* szTitle = pthis->m_szTitle;    CvPoint& prev_pt = pthis->m_prev_pt;    int nThick = pthis->m_nThick;    Mat& Mmid = pthis->m_Mmid;    if(!Mmid.data)        return;    if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽    {        prev_pt = cvPoint(-1, -1);    }    else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键    {        prev_pt = cvPoint(x,y);    }    else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽    {        CvPoint pt = cvPoint(x, y);        if ( prev_pt.x < 0)        {            prev_pt = pt;        }        line(Mmid, prev_pt, pt, Scalar::all(255), nThick ,8,0); //原图上划线        prev_pt = pt;        imshow(szTitle, Mmid);    }    if (event == CV_EVENT_RBUTTONUP)    {        destroyWindow(szTitle);    }}int CCvImage::DrawCurveOnBigImg(Mat Msrc,    int nScreenWidth/* = SCREEN_WIDTH*/, int nScreenHeight/* = SCREEN_HEIGHT*/, char* szTitle/* = "画曲线"*/, int nThick/* = 2*/){    m_Mmid.release();    m_Msrc.release();    float fProportion;    AutoSizeMat(Msrc, m_Mmid, fProportion, nScreenWidth, nScreenHeight);    m_Msrc = Msrc;    //显示原图    imshow(szTitle, m_Mmid);    //鼠标回调函数    this->m_szTitle = szTitle;    this->m_nThick = nThick;    this->m_fProportion = fProportion;    cvSetMouseCallback(szTitle, on_mouse_big_curve, this);    waitKey(0);    destroyWindow(szTitle);    return 0;}void on_mouse_big_curve(int event, int x, int y, int flags, void* pParameters){    CCvImage* pthis = (CCvImage*)pParameters;    //获取相关的参数    char* szTitle = pthis->m_szTitle;    CvPoint& prev_pt = pthis->m_prev_pt;    int nThick = pthis->m_nThick;    Mat& Mmid = pthis->m_Mmid;    if(!Mmid.data)        return;    if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽    {        prev_pt = cvPoint(-1, -1);    }    else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键    {        prev_pt = cvPoint(x,y);    }    else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽    {        CvPoint pt = cvPoint(x, y);        if ( prev_pt.x < 0)        {            prev_pt = pt;        }        line(Mmid, prev_pt, pt, Scalar::all(255), nThick ,8,0); //缩小图上划线        CvPoint t_prev_pt = prev_pt, t_pt = pt;        pthis->ResizePoint(t_prev_pt, pthis->m_fProportion);        pthis->ResizePoint(t_pt, pthis->m_fProportion);        line(pthis->m_Msrc, t_prev_pt, t_pt, Scalar::all(255), nThick ,8,0); //原图上划线        prev_pt = pt;        imshow(szTitle, Mmid);    }    if (event == CV_EVENT_RBUTTONUP)    {        destroyWindow(szTitle);    }}int CCvImage::DrawLineOnImg(Mat Msrc, CvPoint& pStart, CvPoint& pEnd, char* szTitle/* = "画直线"*/, int nThick/* = 2*/){    m_Mmid.release();    Msrc.copyTo(m_Mmid);    //显示原图    imshow(szTitle, m_Mmid);    //鼠标回调函数    this->m_szTitle = szTitle;    this->m_nThick = nThick;    cvSetMouseCallback(szTitle, on_mouse_line, this);    waitKey(0);    pStart = m_prev_pt;    pEnd = m_curr_pt;    destroyWindow(szTitle);    return 0;}int CCvImage::DrawLineOnBigImg(Mat Msrc, CvPoint& pStart, CvPoint& pEnd,    int nScreenWidth/* = SCREEN_WIDTH*/, int nScreenHeight/* = SCREEN_HEIGHT*/, char* szTitle/* = "画直线"*/, int nThick/* = 2*/){    m_Mmid.release();    float fProportion;    AutoSizeMat(Msrc, m_Mmid, fProportion, nScreenWidth, nScreenHeight);    //显示原图    imshow(szTitle, m_Mmid);    //鼠标回调函数    this->m_szTitle = szTitle;    this->m_nThick = nThick;    cvSetMouseCallback(szTitle, on_mouse_line, this);    waitKey(0);    pStart = m_prev_pt;    pEnd = m_curr_pt;    ResizePoint(pStart, fProportion);    ResizePoint(pEnd, fProportion);    destroyWindow(szTitle);    return 0;}void on_mouse_line(int event, int x, int y, int flags, void* pParameters){    CCvImage* pthis = (CCvImage*)pParameters;    //获取相关的参数    char* szTitle = pthis->m_szTitle;    CvPoint curr_pt;    CvPoint prev_pt = pthis->m_prev_pt; //注意这里不是引用    int nThick = pthis->m_nThick;    Mat& Mmid = pthis->m_Mmid;    if(!Mmid.data)        return;    Mat Mori;    if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽    {        prev_pt = cvPoint(-1, -1);    }    else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键    {        prev_pt = cvPoint(x,y);    }    else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽    {        CvPoint pt = cvPoint(x, y);        if ( prev_pt.x < 0)        {            prev_pt = pt;        }        Mori.release();        Mmid.copyTo(Mori);        line(Mori, prev_pt, pt, Scalar::all(255), nThick ,8,0); //原图上划线        curr_pt = pt;        pthis->m_prev_pt = prev_pt;        pthis->m_curr_pt = pt;        imshow(szTitle, Mori);    }    if (event == CV_EVENT_RBUTTONUP)    {        destroyWindow(szTitle);    }}int CCvImage::DrawRectOnImg(Mat Msrc, CvRect& rect, char* szTitle/* = "画矩形"*/, int nThick/* = 2*/){    m_Mmid.release();    Msrc.copyTo(m_Mmid);    //显示原图    imshow(szTitle,m_Mmid);    //鼠标回调函数    this->m_szTitle = szTitle;    this->m_nThick = nThick;    cvSetMouseCallback(szTitle, on_mouse_rect, this);    waitKey(0);    destroyWindow(szTitle);    rect = this->m_rect;    return 0;}int CCvImage::DrawRectOnBigImg(Mat Msrc, CvRect& rect,    int nScreenWidth/* = SCREEN_WIDTH*/, int nScreenHeight/* = SCREEN_HEIGHT*/, char* szTitle/* = "画矩形"*/, int nThick/* = 2*/){    m_Msrc.release();    m_Mmid.release();    m_Msrc = Msrc;    AutoSizeMat(Msrc, m_Mmid, m_fProportion, nScreenWidth, nScreenHeight);    //显示原图    imshow(szTitle,m_Mmid);    //鼠标回调函数    this->m_szTitle = szTitle;    this->m_nThick = nThick;    cvSetMouseCallback(szTitle, on_mouse_rect, this);    waitKey(0);    destroyWindow(szTitle);    rect = this->m_rect;    ResizeRect(rect, m_fProportion);    return 0;}void on_mouse_rect(int event, int x, int y, int flags, void* pParameters){    CCvImage* pthis = (CCvImage*)pParameters;    //获取相关的参数    char* szTitle = pthis->m_szTitle;    CvPoint& prev_pt = pthis->m_prev_pt;    CvRect& rect = pthis->m_rect;    CvRect& RoiRect = pthis->m_CRroi;    int nThick = pthis->m_nThick;    Mat& Mmid = pthis->m_Mmid;    Mat& Msrc = http://www.mamicode.com/pthis->m_Msrc;    if(!Mmid.data)        return;    Mat Mori;    if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽    {        prev_pt = cvPoint(-1, -1);    }    else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键    {        prev_pt = cvPoint(x,y);    }    else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽    {        if (RoiRect.width == -1 || RoiRect.height == -1)        {            CvPoint pt = cvPoint(x, y);            if ( prev_pt.x < 0)            {                prev_pt = pt;            }            Mori.release();            Mmid.copyTo(Mori);            rectangle(Mori, prev_pt, pt, Scalar::all(255), nThick);            rect = cvRect(prev_pt.x, prev_pt.y, pt.x - prev_pt.x, pt.y - prev_pt.y);            imshow(szTitle, Mori);        }        else        {            if (pthis->m_Msrc.cols != pthis->m_Mmid.cols || pthis->m_Msrc.rows != pthis->m_Mmid.rows)            {                IplImage Isrc = pthis->m_Msrc;                CvPoint pt = cvPoint(x, y);                Mat Mr(pthis->m_Msrc, RoiRect);                Mr.copyTo(Mori);                rectangle(Mori, prev_pt, pt, Scalar::all(255), nThick);                rect = cvRect(RoiRect.x + prev_pt.x, RoiRect.y + prev_pt.y, pt.x - prev_pt.x, pt.y - prev_pt.y);                pthis->ResizeRect(rect, 1 / pthis->m_fProportion);                imshow(szTitle, Mori);            }        }    }    if (event == CV_EVENT_LBUTTONDBLCLK)    {        if (RoiRect.width == -1 || RoiRect.height == -1)        {            if (pthis->m_Msrc.cols != pthis->m_Mmid.cols || pthis->m_Msrc.rows != pthis->m_Mmid.rows)            {                IplImage Isrc = pthis->m_Msrc;                CvPoint pt = cvPoint(x, y);                RoiRect = cvRect(x * pthis->m_fProportion - pthis->m_Mmid.cols / 2, y  * pthis->m_fProportion - pthis->m_Mmid.rows / 2, pthis->m_Mmid.cols, pthis->m_Mmid.rows);                pthis->ValidRect(RoiRect, pthis->m_Mmid.cols, pthis->m_Mmid.rows, pthis->m_Msrc.cols, pthis->m_Msrc.rows);                cvSetImageROI(&Isrc, RoiRect);                cvShowImage(szTitle, &Isrc);                cvResetImageROI(&Isrc);            }        }        else        {            Mori.release();            Mmid.copyTo(Mori);            imshow(szTitle, Mori);            pthis->ResetRect(RoiRect);        }    }    if (event == CV_EVENT_RBUTTONUP)    {        destroyWindow(szTitle);    }}int CCvImage::GetMaskByCurve(Mat Msrc, Mat& Mdst, char* szTitle/* = "获取遮罩"*/){    m_Mmid.release();    Msrc.copyTo(m_Mmid);    Mat mask(Msrc.rows, Msrc.cols, CV_8U, Scalar(255));    m_Mmask.release();    m_Mmask = mask;    //显示原图    imshow(szTitle,m_Mmid);    //鼠标回调函数    this->m_szTitle = szTitle;    cvSetMouseCallback(szTitle, on_mouse_curve_mask, this);    waitKey(0);    m_Mmask.copyTo(Mdst);    destroyWindow(szTitle);    return 0;}void on_mouse_curve_mask(int event, int x, int y, int flags, void* pParameters){    CCvImage* pthis = (CCvImage*)pParameters;    //获取相关的参数    char* szTitle = pthis->m_szTitle;    CvPoint& prev_pt = pthis->m_prev_pt;    CvRect& rect = pthis->m_rect;    Mat& Mmid = pthis->m_Mmid;    Mat& Mmask = pthis->m_Mmask;    if(!Mmid.data)        return;    if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽    {        prev_pt = cvPoint(-1, -1);    }    else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键    {        prev_pt = cvPoint(x,y);    }    else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽    {        CvPoint pt = cvPoint(x, y);        if ( prev_pt.x < 0)        {            prev_pt = pt;        }        line(Mmask, prev_pt, pt, Scalar(0),2,8,0); //模板上划线        line(Mmid, prev_pt, pt, Scalar::all(255),2,8,0);          //原图上划线        prev_pt = pt;        imshow(szTitle, Mmid);    }    if (event == CV_EVENT_RBUTTONUP)    {        floodFill(Mmask, Point(x,y), Scalar(0));//填充抠图模板    }}int CCvImage::GetMaskByDaub(Mat Msrc, Mat& Mdst, int nRadius/* = 20*/, char* szTitle/* = "获取遮罩"*/){    m_Mmid.release();    Msrc.copyTo(m_Mmid);    Mat mask(Msrc.rows, Msrc.cols, CV_8U, Scalar(0));    m_Mmask.release();    m_Mmask = mask;    //显示原图    imshow(szTitle,m_Mmid);    //鼠标回调函数    this->m_szTitle = szTitle;    this->m_nThick = nRadius;    cvSetMouseCallback(szTitle, on_mouse_daub, this);    waitKey(0);    m_Mmask.copyTo(Mdst);    destroyWindow(szTitle);    return 0;}void on_mouse_daub(int event, int x, int y, int flags, void* pParameters){    CCvImage* pthis = (CCvImage*)pParameters;    //获取相关的参数    char* szTitle = pthis->m_szTitle;    CvPoint& prev_pt = pthis->m_prev_pt;    int nThick = pthis->m_nThick;    Mat& Mmid = pthis->m_Mmid;    if(!Mmid.data)        return;    if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽    {        prev_pt = cvPoint(-1, -1);    }    else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键    {        prev_pt = cvPoint(x,y);    }    else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽    {        CvPoint pt = cvPoint(x, y);        if ( prev_pt.x < 0)        {            prev_pt = pt;        }        line(pthis->m_Mmask, prev_pt, pt, Scalar(255), nThick, 8, 0); //模板上划线        line(Mmid, prev_pt, pt, Scalar::all(255), nThick, 8, 0);          //原图上划线        prev_pt = pt;        imshow(szTitle, Mmid);    }    if (event == CV_EVENT_RBUTTONUP)    {        destroyWindow(szTitle);    }}int CCvImage::ResetRect(CvRect& rect, int nValue/* = -1*/){    rect.x = nValue;    rect.y = nValue;    rect.width = nValue;    rect.height = nValue;    return 0;}int CCvImage::ResizePoint(CvPoint& Csrc, float fProportion){    Csrc.x *= fProportion;    Csrc.y *= fProportion;    return 0;}int CCvImage::ResizeRect(CvRect& Csrc, float fProportion){    Csrc.x *= fProportion;    Csrc.y *= fProportion;    Csrc.width *= fProportion;    Csrc.height *= fProportion;    return 0;}int CCvImage::ResizeRect(CvRect& rect, int nExpandWidthPixs/* = 0*/, int nExpandHeightPixs/* = 0*/){    rect.x -= nExpandWidthPixs;    rect.y -= nExpandHeightPixs;    rect.width += nExpandWidthPixs * 2;    rect.height += nExpandHeightPixs * 2;    return 0;}int CCvImage::ResizeRect(CvRect& rect, int nLeft, int nRight, int nUp, int nDown){    rect.x -= nLeft;    rect.y -= nUp;    rect.width += nLeft + nRight;    rect.height += nUp + nDown;    return 0;}int CCvImage::ValidExpandValue(const CvRect& CRroi, int& nLeft, int& nRight, int& nUp, int& nDown, int nWidth, int nHeight){    if (CRroi.x < nLeft)    {        nLeft = CRroi.x;    }    if (CRroi.x + CRroi.width + nRight > nWidth)    {        nRight = nWidth - CRroi.x - CRroi.width;    }    if (CRroi.y < nUp)    {        nUp = CRroi.y;    }    if (CRroi.y + CRroi.height + nDown > nHeight)    {        nDown = nHeight - CRroi.y - CRroi.height;    }    return 0;}int CCvImage::ValidRect(CvRect& rect, int nWidth, int nHeight){    if (rect.width < 0 && rect.height < 0 && rect.x >= 0 && rect.x <= nWidth && rect.y >= 0 && rect.y <= nWidth)    {        //反向操作        rect.x += rect.width;        rect.y += rect.height;        rect.width = -rect.width;        rect.height = -rect.height;    }    if (rect.x < 0)    {        rect.x = 0;    }    if (rect.x > nWidth)    {        rect.x = nWidth;    }    if (rect.y > nHeight)    {        rect.y = nHeight;    }    if (rect.y < 0)    {        rect.y = 0;    }    if (rect.x + rect.width > nWidth)    {        rect.width = nWidth - rect.x;    }    if (rect.y + rect.height > nHeight)    {        rect.height = nHeight - rect.y;    }    return 0;}int CCvImage::ValidRect(CvRect& rectSmall, const int nRectWidth, const int nRectHeight, const int nPicWidth, const int nPicHeight){    ValidRect(rectSmall, nPicWidth, nPicHeight);    if (rectSmall.x + nRectWidth > nPicWidth)    {        rectSmall.x = nPicWidth - nRectWidth;        rectSmall.width = nRectWidth;    }    if (rectSmall.y + nRectHeight > nPicHeight)    {        rectSmall.y = nPicHeight -  nRectHeight;        rectSmall.height = nRectHeight;    }    return 0;}

 

OpenCV常用图像操作和鼠标操作(双11版本)