目录
鼠标操作与响应
staticvoidon_draw(int event,int x,int y,int flags,void* userobj){
Mat image =*(Mat*)userobj;if(event == EVENT_LBUTTONDOWN){//鼠标点击时
sp.x = x;
sp.y = y;
std::cout <<"start:"<< sp << std::endl;}if(event == EVENT_LBUTTONUP){//鼠标抬起后
ap.x = x;
ap.y = y;int dx = ap.x - sp.x;int dy = ap.y - sp.y;if(dx >0&& dy >0){
Rect box(sp.x, sp.y, dx, dy);//绘制矩形rectangle(image, box,Scalar(0,0,255),1,8,0);imshow("绘制后", image);}
std::cout <<"end:"<< sp << std::endl;}}voidQuickDemo::mouse_drawing_demo(Mat& image){namedWindow("绘制前", WINDOW_AUTOSIZE);imshow("绘制前", image);//设置回调机制setMouseCallback("绘制前",on_draw,(void*)(&image));}
一个屏幕上只绘制一张图像,当鼠标移动的时候自动清空屏幕
Point sp(-1,-1);
Point ap(-1,-1);
Mat tmp;staticvoidon_draw(int event,int x,int y,int flags,void* userobj){
Mat image =*(Mat*)userobj;if(event == EVENT_LBUTTONDOWN){
sp.x = x;
sp.y = y;
std::cout <<"start: "<< sp << std::endl;}//鼠标松开时确定结尾位置,并绘制矩形elseif(event == EVENT_LBUTTONUP){
ap.x = x;
ap.y = y;int dx = ap.x - sp.x;int dy = ap.y - sp.y;if(sp.x >0&& sp.y >0){
Rect box(sp.x, sp.y, dx, dy);rectangle(image, box,Scalar(0,0,255),2,8,0);imshow("绘制前", image);//绘制完清空
sp.x =-1;
sp.y =-1;}
std::cout <<"end: "<< ap << std::endl;}//当鼠标移动的时候会清空屏幕elseif(event == EVENT_MOUSEMOVE){
tmp.copyTo(image);//清除屏幕}}voidQuickDemo::mouse_drawing_demo(Mat& image){namedWindow("绘制前", WINDOW_AUTOSIZE);imshow("绘制前", image);//设置回调机制setMouseCallback("绘制前",on_draw,(void*)(&image));
tmp = image.clone();}
提取图像框选中部分
Point sp(-1,-1);
Point ap(-1,-1);
Mat tmp;staticvoidon_draw(int event,int x,int y,int flags,void* userobj){
Mat image =*(Mat*)userobj;if(event == EVENT_LBUTTONDOWN){
sp.x = x;
sp.y = y;
std::cout <<"start: "<< sp << std::endl;}//鼠标松开时确定结尾位置,并绘制矩形elseif(event == EVENT_LBUTTONUP){
ap.x = x;
ap.y = y;int dx = ap.x - sp.x;int dy = ap.y - sp.y;if(sp.x >0&& sp.y >0){//防止越界访问
Rect box(sp.x, sp.y, dx, dy);rectangle(image, box,Scalar(0,0,255),2,8,0);imshow("绘制前", image);if(dx >0&& dy >0){//防止越界访问
tmp.copyTo(image);//清楚红边框imshow("ROT截取",image(box));}
sp.x =-1;
sp.y =-1;
std::cout <<"end: "<< ap << std::endl;}}//当鼠标移动的时候会清空屏幕elseif(event == EVENT_MOUSEMOVE){
tmp.copyTo(image);//清除屏幕}}voidQuickDemo::mouse_drawing_demo(Mat& image){namedWindow("绘制前", WINDOW_AUTOSIZE);imshow("绘制前", image);//设置回调机制setMouseCallback("绘制前",on_draw,(void*)(&image));
tmp = image.clone();}
展示效果:
绘制圆形
Point p(-1,-1);
Mat tmp;staticvoidon_draw(int event,int x,int y ,int flags,void*userobj){
Mat image =*(Mat*)userobj;if(event == EVENT_LBUTTONDOWN){
p.x = x;
p.y = y;
std::cout <<"start: "<< p << std::endl;}elseif(event == EVENT_LBUTTONUP){circle(image, p,80,Scalar(0,0,255),-1);imshow("绘制前", image);}elseif(event == EVENT_MOUSEMOVE){
tmp.copyTo(image);//清空屏幕}}voidQuickDemo::mouse_drawing_demo(Mat& image){namedWindow("绘制前", WINDOW_AUTOSIZE);imshow("绘制前", image);//设置回调机制setMouseCallback("绘制前",on_draw,(void*)(&image));
tmp = image.clone();}
鼠标点击某一个点会自动画一个圆形
图像像素归一化
- opencv中提供了四种归一化的方式
- NORM_MINMAX
- NORM_INF
- NORM_L1
- NORM_L2
注:最常用的是NORM_MINMAX归一化方法
voidnormalize(
InputArray src,//输入图像
OutputArray dst,//输出图像 double alpha =1,//NORM_MINMAX时候最低值double beta =0,//NORM_MINMAX时候最高值 int norm_type = NORM_L2,//只有alphaint dtype =-1,//默认类型与src一致
InputArray mask =noArray()//mask默认值为空)
类型转换
- CV_8UC3:3通道每个通道都是RGB 通道 ,每个通道的取值范围是[0, 255],每个通道是8位无符号字节数据类型。
- CV_32F3:3通道每个通道都是RGB 通道 ,每个通道的取值范围是[0, 4294967295],每个通道是32位浮点数数据类型。
voidQuickDemo::norm_demo(Mat& image){
Mat dst;//存储转换后的结果
std::cout << image.type()<< std::endl;//CV_8UC3
image.convertTo(dst, CV_32FC3);
std::cout << dst.type()<< std::endl;//CV_32FC3}
使用normalize函数做归一化处理需要先将CV_8UC3字节类型的图像像素转换为浮点型处理, 因为归一化处理之后的数据范围都在[0, 1]之间,需要用到浮点数保存
voidQuickDemo::norm_demo(Mat& image){
Mat dst;//存储转换后的结果
std::cout << image.type()<< std::endl;//CV_8UC3
image.convertTo(image, CV_32FC3);
std::cout << image.type()<< std::endl;//CV_32FC3normalize(image, dst,1.0,0,NORM_MINMAX);//做归一化处理
std::cout << dst.type()<< std::endl;imshow("类型转换CV_32FC3之后", image);imshow("归一化处理之后", dst);}
将CV_8UC3类型的数据转换成CV_32FC3数据类型后,可以看出图像的像素类型变了之后,与之前的差异比较大,可是做完归一化处理之后在肉眼观察基本上跟原图没有啥区别。
图像放缩插值
voidQuickDemo::resize_demo(Mat& image){
Mat zoomin, zoomout;//放大缩小对象int h = image.rows;//行int w = image.cols;//列//按照宽高进行缩小resize(image, zoomout,Size(h /2, w /2));imshow("缩小", zoomout);//按照宽高进行放大resize(image, zoomin,Size(h *1.5, w *1.5));imshow("放大", zoomin);}
鼠标滚动事件缩小和放大窗口
原理
- 其中scale可以在外部定义为全局变量,通过响应CV_EVENT_MOUSEWHEEL滑轮事件获取Scale的具体值。
- 获取Scale值需要关注两个问题,滑轮滑动的方向和滑动量的大小。滑动方向通过getMouseWheelDelta(flags)获取,
- 当返回值>0时,表示向前滑动;
- 当返回值<0时,表示向后滑动。滑动量根据滑动方向自行设置相应的滑动步长即可。
voidcall_back(int event,int x,int y,int flags,void*userobj){
Mat src =*(Mat*)userobj;
Mat zoominout;int h = src.rows;int w = src.cols;//获取滚动事件if(event == cv::EVENT_MOUSEWHEEL){//获取鼠标上下滚动时的值int Scale =getMouseWheelDelta(flags);if(Scale >0){
Scale = Scale /120+1.5;//放大1.5倍resize(src, zoominout,Size(h * Scale, w * Scale), INTER_LINEAR);}if(Scale <0){
Scale =abs(Scale /120)+1;//缩小2倍resize(src, zoominout,Size(h / Scale, w / Scale), INTER_LINEAR);}imshow("触发后", zoominout);}}voidQuickDemo::mouse_resize_demo(Mat& image){namedWindow("鼠标触发事件", WINDOW_AUTOSIZE);setMouseCallback("鼠标触发事件", call_back,(void*)(&image));imshow("鼠标触发事件", image);}
将鼠标悬浮在鼠标触发事件窗口上,可以使用鼠标的滚轮进行放大和缩小
createTrackbar 创建滚动条的方式调整图片大小
Mat dst, m, src;voidon_track1(int val,void*userobj){int h = src.rows;int w = src.cols;resize(src, dst,Size(h + val, w + val), INTER_LINEAR);imshow("调整后", dst);}voidQuickDemo::mycreateTrackbar(Mat& image){int val =50;
dst =Mat::zeros(image.size(), image.type());
m =Mat::zeros(image.size(), image.type());
src = image.clone();//深拷贝namedWindow("调整", WINDOW_AUTOSIZE);//当滚动按钮被拖动的时候,on_track函数会去调整光的亮度createTrackbar("调整","调整",&val,200, on_track1,(void*)&image);on_track1(50,0);//固定写法imshow("调整", image);}
版权归原作者 爱生活,爱代码 所有, 如有侵权,请联系我们删除。