更新日志:
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 1080
class 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 = -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 = 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;
}