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进行一些简单的自然语言处理的教程
Mar 31 Python
Python函数的周期性执行实现方法
Aug 13 Python
Python获取某一天是星期几的方法示例
Jan 17 Python
Python多继承原理与用法示例
Aug 23 Python
详解python解压压缩包的五种方法
Jul 05 Python
python用for循环求和的方法总结
Jul 08 Python
python3.7简单的爬虫实例详解
Jul 08 Python
Apache部署Django项目图文详解
Jul 30 Python
Python解释器及PyCharm工具安装过程
Feb 26 Python
Python devel安装失败问题解决方案
Jun 09 Python
Python轻量级web框架bottle使用方法解析
Jun 13 Python
使用Keras建立模型并训练等一系列操作方式
Jul 02 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 变量未定义等错误的解决方法
2011/01/12 PHP
fetchAll()与mysql_fetch_array()的区别详解
2013/06/05 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
2016/06/20 PHP
PHP Filter过滤器全面解析
2016/08/09 PHP
TextArea 控件的最大长度问题(js json)
2009/12/16 Javascript
整理8个很棒的 jQuery 倒计时插件和教程
2011/12/12 Javascript
Jquery显示和隐藏元素或设为只读(含Ligerui的控件禁用,实例说明介绍)
2013/07/09 Javascript
jquery合并表格中相同文本的相邻单元格
2015/07/17 Javascript
JS模仿腾讯图片站的图片翻页按钮效果完整实例
2016/06/21 Javascript
jQuery EasyUI tree 使用拖拽时遇到的错误小结
2016/10/10 Javascript
Angular2 之 路由与导航详细介绍
2017/05/26 Javascript
微信小程序图片选择区域裁剪实现方法
2017/12/02 Javascript
webpack4与babel配合使es6代码可运行于低版本浏览器的方法
2018/10/12 Javascript
微信小程序结合mock.js实现后台模拟及调试
2019/03/28 Javascript
浅谈Vue.js 关于页面加载完成后执行一个方法的问题
2019/04/01 Javascript
postman自定义函数实现 时间函数的思路详解
2019/04/17 Javascript
layui prompt 设置允许空白提交的方法
2019/09/24 Javascript
微信小程序wx.request的简单封装
2019/11/13 Javascript
微信小程序实现一个简单swiper代码实例
2019/12/30 Javascript
[01:20]2018DOTA2亚洲邀请赛总决赛战队LGD晋级之路
2018/04/07 DOTA
跟老齐学Python之玩转字符串(3)
2014/09/14 Python
python3 unicode列表转换为中文的实例
2018/10/26 Python
安装Pycharm2019以及配置anconda教程的方法步骤
2019/11/11 Python
python读取图片的几种方式及图像宽和高的存储顺序
2020/02/11 Python
公务员年总结的自我评价
2013/10/25 职场文书
汽车维修与检测专业应届生求职信
2013/11/12 职场文书
信息学院毕业生自荐信范文
2014/03/04 职场文书
师范类求职信
2014/06/21 职场文书
村党支部群众路线教育实践活动对照检查材料
2014/09/26 职场文书
教师思想作风整顿个人剖析材料
2014/10/10 职场文书
2015年管理人员工作总结
2015/05/13 职场文书
2015年工会工作总结范文
2015/07/23 职场文书
Go语言实现Base64、Base58编码与解码
2021/07/26 Golang
详细聊聊关于Mysql联合查询的那些事儿
2021/10/24 MySQL
vue数据字典取键值项目的字典问题
2022/04/12 Vue.js
SpringBoot详解自定义Stater的应用
2022/07/15 Java/Android