opencv图片局部放大镜

本文可以正常运行,请放心使用。
本文参考博客https://blog.csdn.net/pw1623/article/details/88429661,本文系为这篇博客的学习与改进,添加一些详细的注释,弥补原博客的不足之处。
运行结果
在这里插入图片描述在这里插入图片描述
程序源代码(附详细注释)

// fangdaPic.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include "pch.h"
#include <iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
Mat org;//原图
Mat img;//输出图片
Mat imgROI;//感兴趣区域
Mat roiResize;//感兴趣区域ROI的两倍
Mat tranPart;
int foo = 30;//定义尺寸
int fooResize = 2 * foo;//最终显示放大镜的正方形区域的边长,用作下面if的判断

//鼠标回调函数
void on_Mouse(int event, int x, int y, int flag, void*ustc) {
	//形参x,y是鼠标点击的位置
	Mat img_temp = img.clone();//临时变量,存放原图
	//if的作用,x,y是鼠标坐标,限定不能太靠近左上角x > fooResize和 y>fooResize,目的是能让放大镜显示出来。
	//同时限定不能太靠近右下角x<img_temp.cols - fooResize和 y < img_temp.rows - fooResize
	if (x > fooResize && x<img_temp.cols - fooResize && y>fooResize && y < img_temp.rows - fooResize) {
		//感兴趣区域范围
		imgROI = img_temp(Rect(x - foo, y - foo, 2 * foo, 2 * foo));//以(x,y)为中心,左右为foo做正方形
		//tranPart是最后显示放大的区域,这里
		tranPart = img_temp(Range(y - 2 * foo, y + 2 * foo), Range(x - 2 * foo, x + 2 * foo));//Range表示纵、横坐标的范围
		//感兴趣区域放大两倍,需要和tranPart的尺寸搭配。可调,但是注意不能超过图片本身范围。
		resize(imgROI, roiResize, Size(2 * imgROI.cols, 2 * imgROI.rows));//输出到roiResize这个Mat对象中
		roiResize.copyTo(tranPart);//复制到tranPart这个Mat对象中
	//标注鼠标的位置
		circle(img_temp, Point(x, y), 10, Scalar(0, 0, 255), 1, 8, 0);//画一个简单的圆
		imshow("img", img_temp);//显示窗口
	}
}

int main() {
	org = imread("1.jpg");//读取图片,此图片位于同一路径下
	img = org.clone();
	namedWindow("img");//创建opencv窗口
	imshow("img", img);//在窗口显示图片
	setMouseCallback("img", on_Mouse, 0);//调用鼠标回调函数
	waitKey(0);
}

对代码的进一步解释
大家可能对setMouseCallback()这个函数有点陌生。下面解释一下。如下转到定义我们可以看到。
setMouseCallback有三个形参,第一个是const String&类型的变量,需要填写窗口的名称,我们这里是“img”。
第二个形参是MouseCallBack类型的回调函数,第三个形参是void*类型的userdata=0采用默认值。

CV_EXPORTS void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);

/** @brief Gets the mouse-wheel motion delta, when handling mouse-wheel events cv::EVENT_MOUSEWHEEL and
cv::EVENT_MOUSEHWHEEL.在处理鼠标滚轮事件时,获取鼠标滑轮的移动变化。

For cv::EVENT_MOUSEWHEEL positive and negative values mean forward and backward scrolling,
respectively.      EVENT_MOUSEWHEEL正负值意味着向前滚或者向后滚。
 For cv::EVENT_MOUSEHWHEEL, where available, positive and negative values mean right and
left scrolling, respectively.
With the C API, the macro CV_GET_WHEEL_DELTA(flags) can be used alternatively.
有c接口的地方,这个标志可以替代使用。
@note

Mouse-wheel events are currently supported only on Windows.
鼠标滚轮事件目前只支持windows系统
@param flags The mouse callback flags parameter.鼠标回调标志参数
 */

void on_Mouse(int event, int x, int y, int flag, void*ustc) ;
这里的on_Mouse函数一般需要event参数,表示处理事件,在我们的图片局部放大中,我们主要使用的形参是鼠标的坐标(x,y),其他几个变量没有涉及。

总结一下,我们的步骤主要分为以下几步。

第一步,复制到新的临时变量中Mat img_temp = img.clone();//临时变量,存放原图
第二步,考虑最终局部放大的尺寸,限定鼠标位置(x,y)。if (x > fooResize && x<img_temp.cols - fooResize && y>fooResize && y < img_temp.rows - fooResize)
第三步,绘制最初的感兴趣区域ROI,这里是待放大的地方。imgROI = img_temp(Rect(x - foo, y - foo, 2 * foo, 2 * foo));//以(x,y)为中心,左右为foo做正方形
第四步,设置放大后显示的地方与尺寸。tranPart = img_temp(Range(y - 2 * foo, y + 2 * foo), Range(x - 2 * foo, x + 2 * foo));//Range表示纵、横坐标的范围,此处是ROI区域的两倍,需要自己画图体会
第五步,感兴趣区域ROI放大,放到tranPart中。resize(imgROI, roiResize, Size(2 * imgROI.cols, 2 * imgROI.rows));//输出到roiResize这个Mat对象中
roiResize.copyTo(tranPart);//复制到tranPart这个Mat对象中
第六步,显示inshow即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值