Python OpenCV:利用滚动条移动图片,利用鼠标缩放图片

  • 一、实现目标
  • 二、实现背景
  • 三、实现方法
  • 四、运行环境
  • 五、运行代码
  • 六、运行结果
  • 七、不足
  • 八、参考

一、实现目标

  在OpenCV显示比窗口更大的图片,可通过右侧的垂直滚动条和底部的水平滚动条移动图片来显示全图。

二、实现背景

  在OpenCV中,虽然有cv2.getTrackbarPos() 函数,但其作用主要是用作动态调节参数的控件,更准确名称应为滑动条,而非作为滚动条控件使用。经查询发现OpenCV并没有滚动条控件,其对于大于显示窗口的图片来说,OpenCv只能显示原比例图片的部分内容或者缩放后的图片,而无法显示原比例图片的全部内容

三、实现方法

  1. 自己在OpenCv显示窗口画出滚动条,并通过鼠标事件实现其功能(在此详讲的,如果你一定要使用OpenCV界面的话);
  2. 使用其它界面工具如QT等的滚动条控件来实现图片(此方法另谈)。

四、运行环境

  1. 在windows下已安装Python(必须的,我使用的是python3.7);
  2. 安装PyCharm(方便编程调试)
  3. 安装opencv-python(在python下安装配置OpenCV)

五、运行代码

import cv2#鼠标事件
def mouse(event, x, y, flags, param):global flag, horizontal, vertical, flag_hor, flag_ver, dx, dy, sx, sy, dst, x1, y1, x2, y2, x3, y3, f1, f2global zoom, scroll_har, scroll_var, img_w, img_h, img, dst1, win_w, win_h, show_w, show_hif event == cv2.EVENT_LBUTTONDOWN:  # 左键点击if flag == 0:if horizontal and 0 < x < win_w and win_h - scroll_w < y < win_h:flag_hor = 1  # 鼠标在水平滚动条上elif vertical and win_w - scroll_w < x < win_w and 0 < y < win_h:flag_ver = 1  # 鼠标在垂直滚动条上if flag_hor or flag_ver:flag = 1  # 进行滚动条垂直x1, y1, x2, y2, x3, y3 = x, y, dx, dy, sx, sy  # 使鼠标移动距离都是相对于初始滚动条点击位置,而不是相对于上一位置elif event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_LBUTTON):  # 按住左键拖曳if flag == 1:if flag_hor:w = (x - x1)/2  # 移动宽度dx = x2 + w * f1  # 原图xif dx < 0:  # 位置矫正dx = 0elif dx > img_w - show_w:dx = img_w - show_wsx = x3 + w  # 滚动条xif sx < 0:  # 位置矫正sx = 0elif sx > win_w - scroll_har:sx = win_w - scroll_harif flag_ver:h = y - y1  # 移动高度dy = y2 + h * f2  # 原图yif dy < 0:  # 位置矫正dy = 0elif dy > img_h - show_h:dy = img_h - show_hsy = y3 + h  # 滚动条yif sy < 0: # 位置矫正sy = 0elif sy > win_h - scroll_var:sy = win_h - scroll_vardx, dy = int(dx), int(dy)img1 = img[dy:dy + show_h, dx:dx + show_w]  # 截取显示图片print(dy, dy + show_h, dx, dx + show_w)dst = img1.copy()elif event == cv2.EVENT_LBUTTONUP:  # 左键释放flag, flag_hor, flag_ver = 0, 0, 0x1, y1, x2, y2, x3, y3 = 0, 0, 0, 0, 0, 0elif event == cv2.EVENT_MOUSEWHEEL:  # 滚轮if flags > 0:  # 滚轮上移zoom += wheel_stepif zoom > 1 + wheel_step * 20:  # 缩放倍数调整zoom = 1 + wheel_step * 20else:  # 滚轮下移zoom -= wheel_stepif zoom < wheel_step:  # 缩放倍数调整zoom = wheel_stepzoom = round(zoom, 2)  # 取2位有效数字img_w, img_h = int(img_original_w * zoom), int(img_original_h * zoom)  # 缩放都是相对原图,而非迭代img_zoom = cv2.resize(img_original, (img_w, img_h), interpolation=cv2.INTER_AREA)horizontal, vertical = 0, 0if img_h <= win_h and img_w <= win_w:dst1 = img_zoomcv2.resizeWindow("img", img_w, img_h)scroll_har, scroll_var = 0, 0f1, f2 = 0, 0else:if img_w > win_w and img_h > win_h:horizontal, vertical = 1, 1scroll_har, scroll_var = win_w * show_w / img_w, win_h * show_h / img_hf1, f2 = (img_w - show_w) / (win_w - scroll_har), (img_h - show_h) / (win_h - scroll_var)elif img_w > win_w and img_h <= win_h:show_h = img_hwin_h = show_h + scroll_wscroll_har, scroll_var = win_w * show_w / img_w, 0f1, f2 = (img_w - show_w) / (win_w - scroll_har), 0elif img_w <= win_w and img_h > win_h:show_w = img_wwin_w = show_w + scroll_wscroll_har, scroll_var = 0, win_h * show_h / img_hf1, f2 = 0, (img_h - show_h) / (win_h - scroll_var)dx, dy = dx * zoom, dy * zoom  # 缩放后显示图片相对缩放图片的坐标sx, sy = dx / img_w * (win_w - scroll_har), dy / img_h * (win_h - scroll_var)img = img_zoom.copy()  # 令缩放图片为原图dx, dy = int(dx), int(dy)img1 = img[dy:dy + show_h, dx:dx + show_w]dst = img1.copy()if horizontal and vertical:sx, sy = int(sx), int(sy)# 对dst1画图而非dst,避免鼠标事件不断刷新使显示图片不断进行填充dst1 = cv2.copyMakeBorder(dst, 0, scroll_w, 0, scroll_w, cv2.BORDER_CONSTANT, value=[255, 255, 255])cv2.rectangle(dst1, (sx, show_h), (int(sx + scroll_har), win_h), (181, 181, 181), -1)  # 画水平滚动条cv2.rectangle(dst1, (show_w, sy), (win_w, int(sy + scroll_var)), (181, 181, 181), -1)  # 画垂直滚动条elif horizontal == 0 and vertical:sx, sy = int(sx), int(sy)dst1 = cv2.copyMakeBorder(dst, 0, 0, 0, scroll_w, cv2.BORDER_CONSTANT, value=[255, 255, 255])cv2.rectangle(dst1, (show_w, sy), (win_w, int(sy + scroll_var)), (181, 181, 181), -1)  # 画垂直滚动条elif horizontal and vertical == 0:sx, sy = int(sx), int(sy)dst1 = cv2.copyMakeBorder(dst, 0, scroll_w, 0, 0, cv2.BORDER_CONSTANT, value=[255, 255, 255])cv2.rectangle(dst1, (sx, show_h), (int(sx + scroll_har), win_h), (181, 181, 181), -1)  # 画水平滚动条cv2.imshow("img", dst1)cv2.waitKey(1)img_original = cv2.imread("E:\\vs\\image\\2.png")  # 此处需换成大于img_w * img_h的图片
img_original_h, img_original_w = img_original.shape[0:2]  # 原图宽高
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.moveWindow("img", 300, 100)
img = img_original.copy()
img_h, img_w = img.shape[0:2]  # 原图宽高
show_h, show_w = 600, 800  # 显示图片宽高
horizontal, vertical = 0, 0  # 原图是否超出显示图片
dx, dy = 0, 0  # 显示图片相对于原图的坐标
scroll_w = 16  # 滚动条宽度
sx, sy = 0, 0  # 滚动块相对于滚动条的坐标
flag, flag_hor, flag_ver = 0, 0, 0  # 鼠标操作类型,鼠标是否在水平滚动条上,鼠标是否在垂直滚动条上
x1, y1, x2, y2, x3, y3 = 0, 0, 0, 0, 0, 0  # 中间变量
win_w, win_h = show_w + scroll_w, show_h + scroll_w  # 窗口宽高
scroll_har, scroll_var = win_w * show_w / img_w, win_h * show_h / img_h  # 滚动条水平垂直长度
wheel_step, zoom = 0.05, 1  # 缩放系数, 缩放值
zoom_w, zoom_h = img_w, img_h  # 缩放图宽高
f1, f2 = (img_w - show_w) / (win_w - scroll_har), (img_h - show_h) / (win_h - scroll_var)  # 原图可移动部分占滚动条可移动部分的比例if img_h <= show_h and img_w <= show_w:cv2.imshow("img", img)
else:if img_w > show_w:horizontal = 1if img_h > show_h:vertical = 1i = img[dy:dy + show_h, dx:dx + show_w]dst = i.copy()
cv2.resizeWindow("img", win_w, win_h)
cv2.setMouseCallback('img', mouse)cv2.waitKey()
cv2.destroyAllWindows()

六、运行结果

1、水平移动图片(鼠标左键点击水平滚动条区域,一直按住右移):

2、垂直移动图片(鼠标左键点击垂直滚动条区域,按住并下移):

3、鼠标滚轮后转缩小图片

4、鼠标滚轮前转放大图片

七、不足

  水平移动或垂直移动图片后,在放大图片会出现问题。

八、参考

  1. OpenCV-Python 中文教程(段力辉 译)
  2. OpenCV图像窗口滚动条实现

Python OpenCV:利用滚动条移动图片,利用鼠标缩放图片相关推荐

  1. python opencv 实现从一个文件夹中读取图片做切割处理后放入另一个文件夹

    python opencv 实现从一个文件夹中读取图片切割处理后放入另一个文件夹. 实现的功能是把一个文件夹里的图片作处理,即把原图片中心为起点切割成1536*1536的图片,原图片必须大于这个的大小 ...

  2. [python opencv 计算机视觉零基础到实战] 十、图片效果毛玻璃

    一.学习目标 了解高斯模糊的使用方法 了解毛玻璃的图片效果添加 了解如何自己做一个噪声图片 上一篇:[python opencv 计算机视觉零基础到实战] 九.模糊 如有错误欢迎指出~ 二.了解模糊与 ...

  3. python调整屏幕缩放比例_python实现按长宽比缩放图片 python的turtle怎样缩放界面吧...

    python中如何控制GUI界面等比例缩放 root = Tk() # 创建 GUI 主程序 root.geometry('800x800+0+0')#设置界面欢迎来到四十五资源网: 你可以使用网格布 ...

  4. C#,一种简单的方式实现滚动鼠标缩放图片,平移

    1.缩放 private void ImageShow_Load(object sender, EventArgs e){pictureBox1.Load(@"E:\SQ1.jpg" ...

  5. 查看商品图片,鼠标悬浮图片放大js实现

    2010-06-07 10:18:46|分类:Javascript|字号订阅 <%@pagelanguage="java"import="java.util.*&q ...

  6. html 禁止拖动图片,禁止鼠标拖动图片在新窗口打开

    JavaScript1.0+/JScript1.0+/Nav2+/IE3+/Opera3+ 二.基本语法: window.open(pageURL,name,parameters) 其中: pageU ...

  7. java内存图片_Java程序缩放图片时,内存占用令我百思不得其解

    源代码如下,是一个很简单的程序.importjava.awt.FlowLayout;importjava.awt.Image;importjava.io.File;importjava.io.IOEx ...

  8. 用C#编写一个图片浏览器,实现鼠标控制图片的平移缩放与图片的灰度化

    1. 界面设计 如图1 所示:一个名为ImView 的Form 只中包含有一个名为picturebox 的Picturebox.图2 是它的运行结果.该程序的界面设计较为简单,主要根据鼠标行为及键盘按 ...

  9. [python opencv 计算机视觉零基础到实战] 十一找到图片中指定内容

    一.学习目标 了解图片内容定位方法matchTemplate使用 了解minMaxLoc方法使用 上一篇<[python opencv 计算机视觉零基础到实战] 十.图片效果毛玻璃> 如有 ...

最新文章

  1. 结构体中定义函数指针
  2. ecshop“发货查询”中加入收货人、收货地址、发货时间、配送方式
  3. LaTeX实战经验:数学公式环境注意事项
  4. Python3 基础学习笔记 C03【操作列表】
  5. EasyPR车牌识别学习总结
  6. 趣键盘霸榜App Store七天,下一个趣头条诞生?
  7. 用PS制作电子签名方法总结
  8. Excel之DateDif函数
  9. Oracle安装过程中出现的错误指令
  10. vue element-ui列表中el-switch 开关,使用0和1
  11. Linux PPP实现源码分析
  12. 数据分析-面试(SQL真题)
  13. 【2022国赛模拟】逆天题——生成函数、单位根、Pollard-Rho算法
  14. BT源代码学习心得(十三):客户端源代码分析(对等客户的连接建立及其握手协议)
  15. 2565: 最长双回文串
  16. Sublime Plugin - Python PEP8 Autoformat
  17. 随机洗牌算法+matlab,洗牌算法及 random 中 shuffle 方法和 sample 方法浅析
  18. WIN8系统的远程桌面漏洞 利用QQ拼音纯净版实现提权
  19. 计算机开机没有找到引导设备,电脑开机显示没有可以引导的设备
  20. 【名企面试经验-快手-校招提前批】【Java研发工程师】

热门文章

  1. 11月20日云栖精选夜读:围观阿里总部:边喝茶边搞技术是一种怎样的体验?
  2. 计算机内存分为两种他们是,计算机内存主要有哪两种?他们的主要特点是什么?...
  3. 【附源码】计算机毕业设计java兴发农家乐服务管理系统设计与实现
  4. ❤️❤️马上安排!闺女想在游戏里成为【超人】,Python游戏开发模块Pygame系列之【介绍及安装】❤️❤️源码
  5. PageNow企业级数据可视化开发平台
  6. 走进通信:为什么4G信号满格,却上不了网呢
  7. Python 正则提取字符串中的地区
  8. HP LaserJet 1020打印机显示脱机,脱机使用打印机的勾去不掉
  9. java计算机毕业设计工作流流程编辑OA系统MyBatis+系统+LW文档+源码+调试部署
  10. 利用百度地图api将excel中的经纬度数据可视化