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通过90行代码搭建一个音乐搜索工具
Jul 29 Python
Python解惑之整数比较详解
Apr 24 Python
Python实现删除列表中满足一定条件的元素示例
Jun 12 Python
Python探索之Metaclass初步了解
Oct 28 Python
Python使用pickle模块存储数据报错解决示例代码
Jan 26 Python
pytorch对可变长度序列的处理方法详解
Dec 08 Python
搞定这套Python爬虫面试题(面试会so easy)
Apr 03 Python
Pythony运维入门之Socket网络编程详解
Apr 15 Python
Python实现打砖块小游戏代码实例
May 18 Python
python连接打印机实现打印文档、图片、pdf文件等功能
Feb 07 Python
python爬虫工具例举说明
Nov 30 Python
OpenCV-Python实现人脸磨皮算法
Jun 07 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
Gregarius中文日期格式问题解决办法
2008/04/22 PHP
基于magic_quotes_gpc与magic_quotes_runtime的区别与使用介绍
2013/04/22 PHP
php在window iis的莫名问题的测试方法
2013/05/14 PHP
解析php中static,const与define的使用区别
2013/06/18 PHP
thinkPHP查询方式小结
2016/01/09 PHP
分享一个漂亮的php验证码类
2016/09/29 PHP
PHP定义字符串的四种方式详解
2018/02/06 PHP
JS 用6N±1法求素数 实例教程
2009/10/20 Javascript
jQuery 常见开发使用技巧总结
2009/12/26 Javascript
js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)
2012/12/27 Javascript
JavaScript简单实现网页回到顶部功能
2013/11/12 Javascript
JavaScript插件化开发教程(五)
2015/02/01 Javascript
ECMAScript6新增值比较函数Object.is
2015/06/12 Javascript
使用Node.js配合Nginx实现高负载网络
2015/06/28 Javascript
js实现简单秒表走动的时钟特效
2020/03/25 Javascript
jquery制作属于自己的select自定义样式
2015/11/23 Javascript
javascript闭包概念简单解析(推荐)
2016/06/03 Javascript
jquery 实现回车登录详解及实例代码
2016/10/23 Javascript
JS中的数组转变成JSON格式字符串的方法
2017/05/09 Javascript
微信小程序实现收货地址左滑删除
2020/11/18 Javascript
python实现图片九宫格分割
2021/03/07 Python
基于Python实现扑克牌面试题
2019/12/11 Python
解决Alexnet训练模型在每个epoch中准确率和loss都会一升一降问题
2020/06/17 Python
Django后端分离 使用element-ui文件上传方式
2020/07/12 Python
HTML5移动端开发中的Viewport标签及相关CSS用法解析
2016/04/15 HTML / CSS
Desigual英国官网:在线购买原创服装
2018/03/09 全球购物
在weblogic中发布ejb需涉及到哪些配置文件
2012/01/17 面试题
工程总经理工作职责
2013/12/09 职场文书
新入职员工的自我介绍演讲稿
2014/01/02 职场文书
《周恩来的四个昼夜》观后思想汇报范文两篇
2014/09/10 职场文书
群众路线对照检查材料
2014/09/22 职场文书
工作骂脏话检讨书
2014/10/05 职场文书
2014年科研工作总结
2014/12/03 职场文书
劳模事迹材料范文
2014/12/24 职场文书
2015年初中生自我评价范文
2015/03/03 职场文书
文艺部部长竞选稿
2015/11/21 职场文书