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下载FTP上的文件夹的实现代码
Feb 10 Python
从零学python系列之数据处理编程实例(二)
May 22 Python
Python实现Linux下守护进程的编写方法
Aug 22 Python
python图像处理之镜像实现方法
May 30 Python
python爬虫之百度API调用方法
Jun 11 Python
python 读取视频,处理后,实时计算帧数fps的方法
Jul 10 Python
十分钟搞定pandas(入门教程)
Jun 21 Python
python读取当前目录下的CSV文件数据
Mar 11 Python
Python3标准库之dbm UNIX键-值数据库问题
Mar 24 Python
python线程池如何使用
May 28 Python
Python实现冒泡排序算法的完整实例
Nov 04 Python
利用python+request通过接口实现人员通行记录上传功能
Jan 13 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中对数据库操作的封装
2006/10/09 PHP
用PHP写的MySQL数据库用户认证系统代码
2007/03/22 PHP
PHP执行Curl时报错提示CURL ERROR: Recv failure: Connection reset by peer的解决方法
2014/06/26 PHP
百万级别知乎用户数据抓取与分析之PHP开发
2015/09/28 PHP
js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS
2013/11/18 Javascript
jquery datatable后台封装数据示例代码
2014/08/07 Javascript
JavaScript中的Math.SQRT1_2属性使用简介
2015/06/14 Javascript
javascript+ajax实现产品页面加载信息
2015/07/09 Javascript
jquery mobile移动端幻灯片滑动切换效果
2020/04/15 Javascript
TypeScript入门-基本数据类型
2017/03/28 Javascript
JS HTML图片显示Canvas 压缩功能
2017/07/21 Javascript
VUE2实现事件驱动弹窗示例
2017/10/21 Javascript
js实现一个简单的MVVM框架示例
2018/01/15 Javascript
Node.js中DNS模块学习总结
2018/02/28 Javascript
LayUI表格批量删除方法
2018/08/15 Javascript
vue通过video.js解决m3u8视频播放格式的方法
2019/07/30 Javascript
浅谈Vue项目骨架屏注入实践
2019/08/05 Javascript
JavaScript实现简单的图片切换功能(实例代码)
2020/04/10 Javascript
[01:05:41]EG vs Optic Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
Python 冒泡,选择,插入排序使用实例
2015/02/05 Python
Python绘制全球疫情变化地图的实例代码
2020/04/20 Python
教你使用Sublime text3搭建Python开发环境及常用插件安装另分享Sublime text3最新激活注册码
2020/11/12 Python
python 进制转换 int、bin、oct、hex的原理
2021/01/13 Python
全球酒店预订网站:Hotels.com
2016/08/10 全球购物
包装类的功能、种类、常用方法
2012/01/27 面试题
制冷与电控专业应届生求职信
2013/11/11 职场文书
英语国培研修感言
2014/02/13 职场文书
团委书记的竞聘演讲稿
2014/04/24 职场文书
老干部工作先进集体事迹材料
2014/05/21 职场文书
意外死亡赔偿协议书
2014/10/14 职场文书
2014年司法局工作总结
2014/12/11 职场文书
幼儿园开学温馨提示
2015/07/15 职场文书
房产销售员2015年终工作总结
2015/10/22 职场文书
2021-4-5课程——SQL Server查询【3】
2021/04/05 SQL Server
canvas多重阴影发光效果实现
2021/04/20 Javascript
在Python中如何使用yield
2021/06/07 Python