当前位置:首页 » 《资源分享》 » 正文

Python OpenCV实战画图——这次一定能行!爆肝万字,建议点赞收藏~❤️❤️❤️_是Dream呀的博客

4 人参与  2021年10月09日 16:03  分类 : 《资源分享》  评论

点击全文阅读


在这里插入图片描述

📢📢📢📣📣📣
🌻🌻🌻Hello,大家好我叫是Dream呀,一个有趣的Python博主,小白一枚,多多关照😜😜😜
🏅🏅🏅CSDN Python领域新星创作者,大二在读,欢迎大家找我合作学习
💕入门须知:这片乐园从不缺乏天才,努力才是你的最终入场券!🚀🚀🚀
💓最后,愿我们都能在看不到的地方闪闪发光,一起加油进步🍺🍺🍺
🍉🍉🍉“一万次悲伤,依然会有Dream,我一直在最温暖的地方等你”,唱的就是我!哈哈哈~🌈🌈🌈
🌟🌟🌟✨✨✨

Python OpenCV实战——画图:

  • 一、OpenCV实战之画图
    • 1.画直线和矩形
      • 1.1 画直线
      • 1.2 画矩形
    • 2 .画圆形
  • 二、鼠标作为画笔
    • 1.鼠标事件概述
    • 2.鼠标事件发生的结构
      • 2.1event事件列表
      • 2.2 flag列表
      • 2.3代码演示
    • 3.实现一个鼠标事件
      • 3.1创建自定义鼠标回调函数
      • 3.2在__main__部分里,实现回调函数
      • 3.3高逼格代码
  • 三、轨迹栏作为调色板
    • 1.函数cv.getTrackbarPos()
    • 2.函数 cv2.setTrackbarPos()
    • 3.设定开关switch = '0 : OFF \n1 : ON'
  • 📢📢📢最后的福利

前言:在上篇文章中我们已经介绍了Python OpenCV的详细入门基础知识 还看不懂Python OpenCV?不,我不允许!, 接下来让我们利用OpenCV进行一次画图的实战吧!

一、OpenCV实战之画图

1.画直线和矩形

首先定义一个画布:

import numpy as np #1
import cv2 #2
canvas = np.zeros((300, 300, 3), dtype="uint8") #3

我们使用np.zeros()方法构造了一个300*300的NumPy数组,同时分配了三个颜色空间,分别表示Red,Green,Blue,正如zeros名字所描述的一样,这个方法用0填充了这个数组的每一个元素。在np.zeros()的第二个变量是数据类型:dtype。由于我们需要用RGB格式来表示我们的图像,它的取值范围是[0,255],所以我们用“uint8”就显得至关重要了,如果不声明的话np.zeros()默认的变量类型是float64.

1.1 画直线

# 我们定义了一个元组来表示绿色
green = (0, 255, 0) #4

# 我们在canvas上画了一条绿线从坐标(0,0)(300,300),将结果显示出来,并等待按下任意按键
cv2.line(canvas, (0, 0), (300, 300), green) #5
cv2.imshow("Canvas", canvas) #6
cv2.waitKey(0) #7

# 我们定义了一个元组来表示红色,再次强调OpenCV是BGR模式而不是RGB模式
red = (0, 0, 255) #8
# 我们在canvas上画了一条红线从坐标(300,0)(0,300),
#并且该线的线型为3个像素,这也是最后一个参数的含义,然后将结果显示出来,并等待按下任意按键
cv2.line(canvas, (300, 0), (0, 300), red, 3) #9
cv2.imshow("Canvas", canvas) #10
cv2.waitKey(0) #11

cv2.line(canvas, (0, 0), (300, 300), green) 在canvas上画了一条绿线从坐标(0,0)到(300,300)
运行效果:
在这里插入图片描述

1.2 画矩形

我们使用了cv2.rectangle()方法,这个方法与cv2.line()方法用法是一样的:

  1. 第一个参数表示我们想要在canvas这个画布上进行画图,
  2. 第二个参数是我们矩形的开始点(10,10),
  3. 第三个参数是我们矩形的结束点(60,60),通过这两个点我们定义了一个50*50像素大小的区域,
  4. 第四个参数是我们矩形边框的颜色——绿色,然后将结果显示出来,并等待按下任意按键。
  5. 当我们将最后一个设置线型的参数设置为“-1”,我们便可以得到一个填充的矩形。
cv2.rectangle(canvas, (10, 10), (60, 60), green) #12
cv2.imshow("Canvas", canvas) #13
cv2.waitKey(0) #14
# 在第15行代码中,正如我们可以控制话直线的线型粗细程度,我们也可以控制画矩形的线型粗细,
# 在这行代码中最后一个参数“5”,则表示我们将在canvas上画出一个边框粗细为5个像素大小的起点为(50, 200),终点为 (200, 225)的红色矩形,
# 然后将结果显示出来,并等待按下任意按键。
cv2.rectangle(canvas, (50, 200), (200, 225), red, 5) #15
cv2.imshow("Canvas", canvas) #16
cv2.waitKey(0) #17
# 到目前为止,我们画的都是图形的边框,如果我们想要填充这个边框怎么办呢?
# 在第19行代码中:我们画了一个起点为(200,50),终点为(225,125)的蓝色矩形,
# 当我们将最后一个设置线型的参数设置为“-1”,我们便可以得到一个填充蓝色的矩形。
blue = (255, 0, 0) #18
cv2.rectangle(canvas, (200, 50), (225, 125), blue, -1) #19
cv2.imshow("Canvas", canvas) #20

运行效果:
在这里插入图片描述

2 .画圆形

通过cv2.circle()来进行画圆:

  1. 第一个参数表示在canvas上进行绘画,
  2. 第二个参数表示圆心,
  3. 第三个参数表示半径,
  4. 第四个参数表示颜色
import numpy as np #1
import cv2 #2
# 画圆形和画直线和矩形是一样容易的,但是它有有一些不同:
# 我们重新将我们的画板变成一个白板
canvas = np.zeros((300, 300, 3), dtype="uint8") #22
# 我们定义并计算一个中心点的坐标(centerX,centerY),在第1节和第2节我们均提到过shape[0]表示图片的高度,
# shape[1]表示图片的宽度,分别取它们的一半,得到centerY,centerX
(centerX, centerY) = (canvas.shape[1] // 2, canvas.shape[0] // 2) #23
# 定义一个白色的像素
white = (255, 255, 255)  # 24

for r in range(0, 175, 25):   # 25 我们从[0,175)的范围以跨度为25进行循环来取圆的半径
    cv2.circle(canvas, (centerX, centerY), r, white)  #26第26行通过cv2.circle()来进行画圆,
    # 第一个参数表示在canvas上进行绘画,第二个参数表示圆心,第三个参数表示半径,第四个参数表示颜色。然后将结果显示出来,并等待按下任意按键。
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)  #28

运行效果:
在这里插入图片描述

二、鼠标作为画笔

1.鼠标事件概述

opencv可以实现gui拥有的功能——所以,opencv中也包含了鼠标事件——通过点击等等事件,执行相应的回调函数,实现指定的功能,最终实现交互!

2.鼠标事件发生的结构

鼠标回调函数的构造:函数名任意——但是参数应依次包含:event(事件),x, y,flags(标志),param(其它参数)

  1. event:鼠标事件,可用参数对应值代替
  2. x:鼠标x坐标
  3. y:鼠标y坐标
  4. flags:鼠标状态,可用参数对应值代替
  5. param:param是用户定义的传递到setMouseCallback函数调用的参数 补充一下:事件和标志都可以作为事件触发的条件
import cv2 as cv
import numpy as np
def mouse_circle(event, x, y, flags, param):  
	if event == cv.EVENT_LBUTTONDOWN:  # 该事件为鼠标左键按下
		pass  # 执行任务

2.1event事件列表

opencv下包含的所有事件——包含flag和event事件列表:

  1. if event == cv.EVENT_LBUTTONDBLCLK: # 触发事件为左键双击

  2. if event ==cv.EVENT_LBUTTONDOWN: # 触发事件为左键按下时

  3. if event == cv.EVENT_LBUTTONUP: #触发事件为左键弹起时

  4. if event == cv.EVENT_RBUTTONDBLCLK: # 触发事件为右键双击时

  5. if event== cv.EVENT_RBUTTONDOWN: # 触发事件为右键按下时

  6. if event == cv.EVENT_RBUTTONUP: # 触发事件为右键弹起时

  7. if event == cv.EVENT_MBUTTONDBLCLK:# 触发事件为中键滚轮双击时

  8. if event == cv.EVENT_MBUTTONDOWN: # 触发事件为中键滚轮按下时

  9. if event == cv.EVENT_MBUTTONUP: # 触发事件为中键滚轮弹起时

  10. if event ==cv.EVENT_MOUSEWHEEL: # 触发事件为中键滚轮滚动时

  11. if event == cv.EVENT_MOUSEMOVE:# 触发事件为鼠标移动时

2.2 flag列表

  1. if flags == cv.EVENT_FLAG_ALTKEY: # 触发标志为ALT键按下时
  2. if flags ==cv.EVENT_FLAG_CTRLKEY: # 触发标志为CTRL键按下时
  3. if flags ==cv.EVENT_FLAG_LBUTTON: # 触发标志为鼠标左键按下时
  4. if flags ==cv.EVENT_FLAG_MBUTTON: # 触发标志为鼠标中键滚轮按下时
  5. if flags ==cv.EVENT_FLAG_RBUTTON: # 触发标志为鼠标右键按下时
  6. if flags ==cv.EVENT_FLAG_SHIFTKEY: # 触发标志为SHIFT键按下时

2.3代码演示

用鼠标的回调函数在我们双击的地方绘制一个圆圈:

import numpy as np
import cv2 as cv
# 鼠标回调函数
def draw_circle(event,x,y,flags,param):
    if event == cv.EVENT_LBUTTONDBLCLK:
        cv.circle(img,(x,y),100,(255,0,0),-1)
# 创建一个黑色的图像,一个窗口,并绑定到窗口的功能
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)
while(1):
    cv.imshow('image',img)
    if cv.waitKey(20) & 0xFF == ord('q'):
        break
cv.waitKey(0)
cv.destroyAllWindows()

效果展示:
在这里插入图片描述

3.实现一个鼠标事件

3.1创建自定义鼠标回调函数

我们这里用到event——事件参数,当然,你可以修改它的名字

import cv2 as cv
import numpy as np

cv.setMouseCallback('imag', mouse_circle) 
 # 第一个参数为窗体名称——指的是哪个窗体下执行
 # 第二个参数为鼠标回调函数的名称——传入函数名称,指的是传入整个函数声明,而不是直接执行函数

def mouse_circle(event, x, y, flags, param):
    if event == cv.EVENT_LBUTTONDOWN:  # 触发事件为左键按下时
        cv.rectangle(img, (x, y), (x+88, y+88), (174, 238, 238), -1)  # 画一个88*88的GhostWhite(颜色)矩形

3.2在__main__部分里,实现回调函数

需要先创建一张照片(图像),接着创建一个窗体——然后把后边涉及的相关窗体放在同一个窗体下!!!(回调函数的实现也是挂在同一个窗体下的哦,要一一对应)

if __name__ == "__main__":
    img = np.zeros((512, 512, 3), np.uint8)
    cv.namedWindow('imag', cv.WINDOW_NORMAL)  # 创建一个可改变大小的窗体
    cv.resizeWindow('imag', 510, 510)  # 大小设置
    cv.setMouseCallback('imag', mouse_circle)  # 实现鼠标回调函数到imag的窗体
    while True:
        cv.imshow('imag', img)
        k = cv.waitKey(10) & 0xFF  # 读取按键
        if k == ord('q') or k == ord('Q'):  # 结束绘制
            break
    cv.destroyAllWindows()

效果演示:
在这里插入图片描述

3.3高逼格代码

现在实现一个更高级的应用,类似画图工具一样,要么画圆,要么画矩形,依照选择的模式来实现,所以鼠标回调函数有两部分,一个用来画矩形,一个用来画圆。这个例子灰常有用,尤其是在交互式应用像是目标追踪和图像分割。
ps(有时间我一定看)

import numpy as np
import cv2

drawing = False #鼠标按下为真
mode = True #如果为真,画矩形,按m切换为曲线
ix,iy=-1,-1

def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy=x,y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                cv2.circle(img,(x,y),5,(0,0,255),-1)
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        else:
            cv2.circle(img,(x,y),5,(0,0,255),-1)


img = np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

while(1):
    cv2.imshow('image',img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m') :
        mode = not mode 
    elif k == 27:
        break
cv2.destroyAllWindows()

效果展示:
在这里插入图片描述

三、轨迹栏作为调色板

将创建一个简单的应用程序,以显示您指定的颜色。您有一个显示颜色的窗口,以及三个用于指定B、G、R颜色的跟踪栏。滑动轨迹栏,并相应地更改窗口颜色。默认情况下,初始颜色将设置为黑色。

1.函数cv.getTrackbarPos()

功能: 得到滑动条的数值

  1. 第一个参数是轨迹栏名称,
  2. 第二个参数是它附加到的窗口名称,
  3. 第三个参数是默认值,
  4. 第四个参数是最大值,
  5. 第五个是执行的回调函数每次跟踪栏值更改。
  6. 回调函数始终具有默认参数,即轨迹栏位置。

2.函数 cv2.setTrackbarPos()

功能:
设置滑动条的默认值

参数:

  1. 第一个参数是滑动条名字,
  2. 第二个时所在窗口,
  3. 第三个参数是滑动条默认值,

3.设定开关switch = ‘0 : OFF \n1 : ON’

创建了一个开关,只有在该开关为ON的情况下,该应用程序才能在其中运行,否则屏幕始终为黑色。

import numpy as np
import cv2 as cv
def nothing(x):
    pass
# 创建一个黑色的图像,一个窗口
img = np.zeros((300,512,3), np.uint8)
cv.namedWindow('image')
# 创建颜色变化的轨迹栏
cv.createTrackbar('R','image',0,255,nothing)
cv.createTrackbar('G','image',0,255,nothing)
cv.createTrackbar('B','image',0,255,nothing)
# 为 ON/OFF 功能创建开关
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image',0,1,nothing)
while(1):
    cv.imshow('image',img)
    k = cv.waitKey(1) & 0xFF
    if k == 27:
        break
    # 得到四条轨迹的当前位置
    r = cv.getTrackbarPos('R','image')
    g = cv.getTrackbarPos('G','image')
    b = cv.getTrackbarPos('B','image')
    s = cv.getTrackbarPos(switch,'image')
    if s == 0:
        img[:] = 0
    else:
        img[:] = [b,g,r]
cv.destroyAllWindows()

在这里插入图片描述

📢📢📢最后的福利

☀️☀️☀️最后一点小福利带给大家:如果想快速上手python的小伙伴们,这个详细整理PPT可以迅速帮助大家打牢python基础,需要的小伙伴们可以下载一下 Python入门基础教程全套+小白速成+学不会来找我! 🍻🍻🍻
还有自制表白神器,需要自取:
Python表白神器,源码+解析+各种完美配置+浪漫新颖 🍻🍻🍻
在这里插入图片描述
🌲🌲🌲 好啦,这就是今天要分享给大家的全部内容了
❤️❤️❤️如果你喜欢的话,就不要吝惜你的一键三连了~
在这里插入图片描述
在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/29680.html

鼠标  参数  事件  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1