opencv给图片加滑动条调节窗口大小

起因:最近对图片进行截取矩形区域操作时,发现了opencv一个很蛋痛的地方,使用imshow()函数展示图片的时候,一旦图片的分辨率过高,就不能完全显示。要是调整参数为WINDOWSIZE_NORMAL的话,截取出来的矩形区域和原图并不是一一对应的。使用resize函数的话,先缩小在放大又会使图片变得异常模糊。只好上网查了一下给图片加上滑动条的文章,然而只找到了opecv2写的函数,现用opencv4重写如下。
目的:给分辨率过大的图片加上滑动条。
原理:截取原图中符合窗口大小的部分并在窗口中显示
代码:

#include<opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int h_x=0, v_y=0,d_x=0,d_y=0;  //记录滑动条变化值,以及保存当前值
Rect v_bar, h_bar;
Point start;  //移动鼠标时的基点,使用了全局变量以使得滑动条的位置可以被记录下来。也可设为局部的静态变量
bool x_change = false;
bool y_change = false; //判断是否改变

void on_mouse(int event, int x, int y, int flags, void* param);
void draw_scrolls(Mat src_img, const char* title, int width = 500, int height = 700);   //后两个参数设置窗口的默认大小


int main()
{
	const char* title = "source";
	Mat srcimg = imread("E:\\material\\shaoyun.jpg");
	namedWindow(title, 1);
	setMouseCallback(title, on_mouse);
	while (true)
	{
		char c = waitKey(10);
		draw_scrolls(srcimg,title);
		if (c == ' ')
			break;
	}

}

void draw_scrolls(Mat src_img, const char* title, int width, int height)
{
	Mat temp_img, src_rect, temp_rect;
	Mat src_roi;
	Rect v_rect,h_rect;
	int img_width, img_height;  //img的width和height
	int win_width, win_height;  //window的width和height
	int show_width, show_height;  //窗口中图片的width和height
	int bar_width=25;  //滑动条的宽度
	double scale_h, scale_w;  //img和window的width,height之比
	int img_y=0,img_x=0;  //上下滑动后截取图片左上顶点的y值,左右滑动后截取图片左上角x值





	img_width = src_img.cols;
	img_height = src_img.rows;
	win_width=show_width = min(img_width,width);
	win_height=show_height = min(img_height,height);
	scale_h = (double)img_height / height;
	scale_w = (double)img_width / width;

	//高度过高需要加竖直滑动
	if (scale_h>1)
	{
		win_width = img_width > width ? width + bar_width : img_width + bar_width;
		show_width = win_width - bar_width;
	}
	//宽度过宽需要加水平滑动
	if (scale_w>1)
	{
		win_height = img_height > height ? height + bar_width : img_height + bar_width;
		show_height = win_height - bar_width;
	}

	temp_img = Mat::zeros(Size(win_width, win_height), CV_8UC3);

	if (scale_h > 1)
	{
		v_y += d_y;
		d_y = 0;
		v_y = v_y < 0 ? 0 : (v_y > (int)((1 - 1 / scale_h) * win_height) ? (int)((1 - 1 / scale_h) * win_height) : v_y);
		img_y = (int)(v_y * img_height / win_height);//img_y = (int)(v_y / ((1-1/scale_h) * win_height) * (1 - 1 / scale_h)*img_height)的简化

		v_rect = Rect(show_width + 1, 0, bar_width, win_height);  //竖直滑动条底层
		v_bar = Rect(show_width + 1, v_y, bar_width, (int)((double)win_height / scale_h));  //竖直滑动条
		rectangle(temp_img, v_rect, Scalar::all(0), -1);
		rectangle(temp_img, v_bar, Scalar::all(255), -1);
	}
	if (scale_w > 1)
	{
		h_x+=d_x;
		d_x = 0;
		h_x = h_x < 0 ? 0 : (h_x > (int)((1 - 1 / scale_w) * win_width) ? (int)((1 - 1 / scale_w) * win_width) : h_x);
		img_x = (int)(h_x * img_width / win_width);  //同上

		h_rect = Rect(0, show_height + 1, win_width, bar_width);  //水平滑动条底层
		h_bar = Rect(h_x, show_height + 1, (int)((double)win_width / scale_w), bar_width);   //水平滑动条
		rectangle(temp_img, h_rect, Scalar::all(0), -1);
		rectangle(temp_img, h_bar, Scalar::all(255), -1);
	}
	temp_rect = temp_img(Rect(0, 0, show_width, show_height));   //窗口显示图片部分
	src_rect = src_img(Rect(img_x, img_y, show_width, show_height));   //原图截取部分
	src_rect.copyTo(temp_rect);
	imshow(title, temp_img);

}

void on_mouse(int event, int x, int y, int flags, void* param)
{
	Point curse = Point(x, y);
	Point now;
	//点击竖直滑动条
	if (v_bar.contains(curse))
	{
		if (event == EVENT_LBUTTONDOWN)
		{
			start = Point(x, y);
			y_change = true;
		}
	}
	//点击水平滑动条
	if (h_bar.contains(curse))
	{ 
		if (event == EVENT_LBUTTONDOWN)
		{
			start = Point(x, y);
			x_change = true;
		}
	}

	//拖动
	if (event == EVENT_MOUSEMOVE)
	{
		now = Point(x, y);
		if (y_change)
		{
			d_y = now.y - start.y;
			start = now;
		}
		if (x_change)
		{
			d_x = now.x - start.x;
			start = now;
		}
	}
	if (event == EVENT_LBUTTONUP)
	{
		x_change = y_change = false;
	}
}

原图:
1920*1080
效果图:
在这里插入图片描述
————————————————
版权声明:本文为CSDN博主「三更打雨」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Dr_maker/article/details/100833890

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV中,可以使用滑动调节图像的亮度、对比度等参数。引用\[1\]中的代码演示了如何使用滑动调节图像的卷积核大小,从而改变图像的形态学操作效果。而引用\[2\]中的示例代码展示了如何使用滑动调节图像的亮度,通过改变滑动的值来实时调整图像的亮度。最后,引用\[3\]中的示例代码展示了如何使用滑动来绘制图像的轨迹。通过鼠标左键点击并拖动,可以在图像上绘制出轨迹线。这些示例代码可以帮助你理解如何在OpenCV中使用滑动调节图像。 #### 引用[.reference_title] - *1* [opencv学习-滑动及其应用](https://blog.csdn.net/weixin_51244852/article/details/118339355)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [OpenCV学习笔记(七)——窗口交互操作(图像窗口滑动、鼠标响应事件)](https://blog.csdn.net/a1016249126/article/details/123782850)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值