Python OpenCV实现鼠标画框效果


Posted in Python onAugust 19, 2020

使用Python+OpenCV实现鼠标画框的代码,供大家参考,具体内容如下

Python OpenCV实现鼠标画框效果

# -*-coding: utf-8 -*-
"""
 @Project: IntelligentManufacture
 @File : user_interaction.py
 @Author : panjq
 @E-mail : pan_jinquan@163.com
 @Date : 2019-02-21 15:03:18
"""
# -*- coding: utf-8 -*-
 
import cv2
from utils import image_processing
import numpy as np
global img
global point1, point2
global g_rect
 
def on_mouse(event, x, y, flags, param):
 global img, point1, point2,g_rect
 img2 = img.copy()
 if event == cv2.EVENT_LBUTTONDOWN: # 左键点击,则在原图打点
 print("1-EVENT_LBUTTONDOWN")
 point1 = (x, y)
 cv2.circle(img2, point1, 10, (0, 255, 0), 5)
 cv2.imshow('image', img2)
 
 elif event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_LBUTTON): # 按住左键拖曳,画框
 print("2-EVENT_FLAG_LBUTTON")
 cv2.rectangle(img2, point1, (x, y), (255, 0, 0), thickness=2)
 cv2.imshow('image', img2)
 
 elif event == cv2.EVENT_LBUTTONUP: # 左键释放,显示
 print("3-EVENT_LBUTTONUP")
 point2 = (x, y)
 cv2.rectangle(img2, point1, point2, (0, 0, 255), thickness=2)
 cv2.imshow('image', img2)
 if point1!=point2:
  min_x = min(point1[0], point2[0])
  min_y = min(point1[1], point2[1])
  width = abs(point1[0] - point2[0])
  height = abs(point1[1] - point2[1])
  g_rect=[min_x,min_y,width,height]
  cut_img = img[min_y:min_y + height, min_x:min_x + width]
  cv2.imshow('ROI', cut_img)
 
def get_image_roi(rgb_image):
 '''
 获得用户ROI区域的rect=[x,y,w,h]
 :param rgb_image:
 :return:
 '''
 bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)
 global img
 img=bgr_image
 cv2.namedWindow('image')
 while True:
 cv2.setMouseCallback('image', on_mouse)
 # cv2.startWindowThread() # 加在这个位置
 cv2.imshow('image', img)
 key=cv2.waitKey(0)
 if key==13 or key==32:#按空格和回车键退出
  break
 cv2.destroyAllWindows()
 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 return g_rect
 
def select_user_roi(image_path):
 '''
 由于原图的分辨率较大,这里缩小后获取ROI,返回时需要重新scale对应原图
 :param image_path:
 :return:
 '''
 orig_image = image_processing.read_image(image_path)
 orig_shape = np.shape(orig_image)
 resize_image = image_processing.resize_image(orig_image, resize_height=800,resize_width=None)
 re_shape = np.shape(resize_image)
 g_rect=get_image_roi(resize_image)
 orgi_rect = image_processing.scale_rect(g_rect, re_shape,orig_shape)
 roi_image=image_processing.get_rect_image(orig_image,orgi_rect)
 image_processing.cv_show_image("RECT",roi_image)
 image_processing.show_image_rect("image",orig_image,orgi_rect)
 return orgi_rect
 
 
if __name__ == '__main__':
 # image_path="../dataset/images/IMG_0007.JPG"
 image_path="../dataset/test_images/lena.jpg"
 
 # rect=get_image_roi(image)
 rect=select_user_roi(image_path)
 print(rect)

其中image_processing.py文件如下:

# -*-coding: utf-8 -*-
"""
 @Project: IntelligentManufacture
 @File : image_processing.py
 @Author : panjq
 @E-mail : pan_jinquan@163.com
 @Date : 2019-02-14 15:34:50
"""
 
import os
import glob
import cv2
import numpy as np
import matplotlib.pyplot as plt
 
def show_image(title, image):
 '''
 调用matplotlib显示RGB图片
 :param title: 图像标题
 :param image: 图像的数据
 :return:
 '''
 # plt.figure("show_image")
 # print(image.dtype)
 plt.imshow(image)
 plt.axis('on') # 关掉坐标轴为 off
 plt.title(title) # 图像题目
 plt.show()
 
def cv_show_image(title, image):
 '''
 调用OpenCV显示RGB图片
 :param title: 图像标题
 :param image: 输入RGB图像
 :return:
 '''
 channels=image.shape[-1]
 if channels==3:
 image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # 将BGR转为RGB
 cv2.imshow(title,image)
 cv2.waitKey(0)
 
def read_image(filename, resize_height=None, resize_width=None, normalization=False):
 '''
 读取图片数据,默认返回的是uint8,[0,255]
 :param filename:
 :param resize_height:
 :param resize_width:
 :param normalization:是否归一化到[0.,1.0]
 :return: 返回的RGB图片数据
 '''
 
 bgr_image = cv2.imread(filename)
 # bgr_image = cv2.imread(filename,cv2.IMREAD_IGNORE_ORIENTATION|cv2.IMREAD_COLOR)
 if bgr_image is None:
 print("Warning:不存在:{}", filename)
 return None
 if len(bgr_image.shape) == 2: # 若是灰度图则转为三通道
 print("Warning:gray image", filename)
 bgr_image = cv2.cvtColor(bgr_image, cv2.COLOR_GRAY2BGR)
 
 rgb_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2RGB) # 将BGR转为RGB
 # show_image(filename,rgb_image)
 # rgb_image=Image.open(filename)
 rgb_image = resize_image(rgb_image,resize_height,resize_width)
 rgb_image = np.asanyarray(rgb_image)
 if normalization:
 # 不能写成:rgb_image=rgb_image/255
 rgb_image = rgb_image / 255.0
 # show_image("src resize image",image)
 return rgb_image
def resize_image(image,resize_height, resize_width):
 '''
 :param image:
 :param resize_height:
 :param resize_width:
 :return:
 '''
 image_shape=np.shape(image)
 height=image_shape[0]
 width=image_shape[1]
 if (resize_height is None) and (resize_width is None):#错误写法:resize_height and resize_width is None
 return image
 if resize_height is None:
 resize_height=int(height*resize_width/width)
 elif resize_width is None:
 resize_width=int(width*resize_height/height)
 image = cv2.resize(image, dsize=(resize_width, resize_height))
 return image
def scale_image(image,scale):
 '''
 :param image:
 :param scale: (scale_w,scale_h)
 :return:
 '''
 image = cv2.resize(image,dsize=None, fx=scale[0],fy=scale[1])
 return image
 
 
def get_rect_image(image,rect):
 '''
 :param image:
 :param rect: [x,y,w,h]
 :return:
 '''
 x, y, w, h=rect
 cut_img = image[y:(y+ h),x:(x+w)]
 return cut_img
def scale_rect(orig_rect,orig_shape,dest_shape):
 '''
 对图像进行缩放时,对应的rectangle也要进行缩放
 :param orig_rect: 原始图像的rect=[x,y,w,h]
 :param orig_shape: 原始图像的维度shape=[h,w]
 :param dest_shape: 缩放后图像的维度shape=[h,w]
 :return: 经过缩放后的rectangle
 '''
 new_x=int(orig_rect[0]*dest_shape[1]/orig_shape[1])
 new_y=int(orig_rect[1]*dest_shape[0]/orig_shape[0])
 new_w=int(orig_rect[2]*dest_shape[1]/orig_shape[1])
 new_h=int(orig_rect[3]*dest_shape[0]/orig_shape[0])
 dest_rect=[new_x,new_y,new_w,new_h]
 return dest_rect
 
def show_image_rect(win_name,image,rect):
 '''
 :param win_name:
 :param image:
 :param rect:
 :return:
 '''
 x, y, w, h=rect
 point1=(x,y)
 point2=(x+w,y+h)
 cv2.rectangle(image, point1, point2, (0, 0, 255), thickness=2)
 cv_show_image(win_name, image)
 
def rgb_to_gray(image):
 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
 return image
 
def save_image(image_path, rgb_image,toUINT8=True):
 if toUINT8:
 rgb_image = np.asanyarray(rgb_image * 255, dtype=np.uint8)
 if len(rgb_image.shape) == 2: # 若是灰度图则转为三通道
 bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_GRAY2BGR)
 else:
 bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)
 cv2.imwrite(image_path, bgr_image)
 
def combime_save_image(orig_image, dest_image, out_dir,name,prefix):
 '''
 命名标准:out_dir/name_prefix.jpg
 :param orig_image:
 :param dest_image:
 :param image_path:
 :param out_dir:
 :param prefix:
 :return:
 '''
 dest_path = os.path.join(out_dir, name + "_"+prefix+".jpg")
 save_image(dest_path, dest_image)
 
 dest_image = np.hstack((orig_image, dest_image))
 save_image(os.path.join(out_dir, "{}_src_{}.jpg".format(name,prefix)), dest_image)
 
if __name__=="__main__":
 image_path="../dataset/test_images/src.jpg"
 image = read_image(image_path, resize_height=None, resize_width=None)
 image = rgb_to_gray(image)
 orig_shape=np.shape(image)#shape=(h,w)
 orig_rect=[50,100,100,200]#x,y,w,h
 print("orig_shape:{}".format(orig_shape))
 show_image_rect("orig",image,orig_rect)
 
 dest_image=resize_image(image,resize_height=None,resize_width=200)
 dest_shape=np.shape(dest_image)
 print("dest_shape:{}".format(dest_shape))
 dest_rect=scale_rect(orig_rect, orig_shape, dest_shape)
 show_image_rect("dest",dest_image,dest_rect)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
从Python程序中访问Java类的简单示例
Apr 20 Python
Python类属性与实例属性用法分析
May 09 Python
基于wxpython实现的windows GUI程序实例
May 30 Python
Python探索之创建二叉树
Oct 25 Python
用Python写脚本,实现完全备份和增量备份的示例
Apr 29 Python
儿童学习python的一些小技巧
May 27 Python
和孩子一起学习python之变量命名规则
May 27 Python
python中将zip压缩包转为gz.tar的方法
Oct 18 Python
python 字典 setdefault()和get()方法比较详解
Aug 07 Python
python和php学习哪个更有发展
Jun 17 Python
如何利用Python给自己的头像加一个小国旗(小月饼)
Oct 02 Python
Python如何解决secure_filename对中文不支持问题
Jul 16 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
Apr 18 #Python
python点击鼠标获取坐标(Graphics)
Aug 10 #Python
python matplotlib库直方图绘制详解
Aug 10 #Python
python字典的遍历3种方法详解
Aug 10 #Python
python命名空间(namespace)简单介绍
Aug 10 #Python
简单介绍python封装的基本知识
Aug 10 #Python
nginx黑名单和django限速,最简单的防恶意请求方法分享
Aug 09 #Python
You might like
php中如何判断一个网页请求是ajax请求还是普通请求
2013/08/10 PHP
PHP代码优化之成员变量获取速度对比
2014/02/28 PHP
php 创建以UNIX时间戳命名的文件夹(示例代码)
2014/03/08 PHP
php+mysqli使用预处理技术进行数据库查询的方法
2015/01/28 PHP
javascript基础的动画教程,直观易懂
2007/01/10 Javascript
jQuery.get、jQuery.getJSON、jQuery.post无法返回JSON问题的解决方法
2011/07/28 Javascript
poshytip 基于jquery的 插件 主要用于显示微博人的图像和鼠标提示等
2012/10/12 Javascript
Javascript跨域请求的4种解决方式
2013/03/17 Javascript
JavaScript的漂亮的代码片段
2013/06/05 Javascript
js复制网页内容并兼容各主流浏览器的代码
2013/12/17 Javascript
js判断横竖屏及禁止浏览器滑动条示例
2014/04/29 Javascript
深入理解JavaScript系列(18):面向对象编程之ECMAScript实现
2015/03/05 Javascript
每个程序员都需要学习 JavaScript 的7个理由小结
2016/09/03 Javascript
JQuery PHP图片在线裁剪实例
2020/07/27 Javascript
详解Node 定时器
2018/02/26 Javascript
详解Nodejs mongoose
2018/06/10 NodeJs
js实现多个倒计时并行 js拼团倒计时
2019/02/25 Javascript
vue中@change兼容问题详解
2019/10/25 Javascript
node.js基础知识汇总
2020/08/25 Javascript
解决Python3 被PHP程序调用执行返回乱码的问题
2019/02/16 Python
Python3标准库总结
2019/02/19 Python
python下载微信公众号相关文章
2019/02/26 Python
Win系统PyQt5安装和使用教程
2019/12/25 Python
pandas中的数据去重处理的实现方法
2020/02/10 Python
实现ECharts双Y轴左右刻度线一致的例子
2020/05/16 Python
Python3交互式shell ipython3安装及使用详解
2020/07/11 Python
Python中qutip用法示例详解
2020/10/02 Python
Python爬虫自动化爬取b站实时弹幕实例方法
2021/01/26 Python
华为旗下电子商务平台:华为商城
2016/08/06 全球购物
有影响力的品牌之家:Our Social Collective
2019/06/08 全球购物
英文求职信结束语大全
2013/10/26 职场文书
西北政法大学自主招生自荐信
2014/01/29 职场文书
检察机关个人对照检查材料
2014/09/15 职场文书
领导干部“四风”查摆问题个人整改措施
2014/10/28 职场文书
Django项目配置Memcached和Redis, 缓存选择哪个更有优势
2021/04/06 Python
Mysql Online DDL的使用详解
2021/05/20 MySQL