文章目录摘要Numpy的ndarray数据结构的索引与赋值创建空白画布初始化白色的画布初始化彩色的画布利用cv2的内置方法merge与split 利用numpy内置的索引综合实验-初始化背景「
在这篇文章中将给大家讲解如何分别用numpy的方法,与numpy与cv2结合的方法创建空白画布,创建白色画布,与创建彩色画布。在讲解过程中还会介绍cv2进行通道分割cv2.split与通道合并cv2.merge的两个函数的具体使用以及深究numpy的ndarray数据结构的索引与赋值。
这里多说一句,小编是一名python开发工程师,这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以关注小编,并私信“01”即可领取。
numpy的ndarray数据结构的索引与赋值在使用画图工具的时候, 第一件事情就是创建一个新的空白画布,我们可以指定画布的大小和颜色。
那我们如何使用opencv来创建一个空白的画布(值相同的图片) ?
其实image的数据结构上的图片,本质上就是numpy里面的ndarray的对象,创建一个画布本质上就是创建一个同等规格的ndarray。
创建一个新的特定尺寸的ndarray我们可以使用np.zeors 函数,我们将图像的高度(height),图像的宽度(width),以及图像的通道数channel 以tuple 类型传入np.zeros。再次声明是tuple类型。
另外由于不是所有的numpy类型的数值,都可以放到opencv中进行图像处理.
数值取值范围在0-255, 我们需要指定数据类型为uint8 unsigned integer 8-bit
np.zeros((height, width, channels), dtype="uint8")1复制代码举个例子:想创建一个800 x 600 x 3 的图片,一个BGR格式的图像,我们就得这么写:
# 初始化一个空画布 300×300 三通道 背景色为黑色 canvas_black = np.zeros((600, 800, 3), dtype="uint8")12复制代码得到的效果如下:
注意: height写在前面为什么Height写在前面?就得知道opencv图像的数据结构是numpy,Image的属性,其实就是numpy的ndarray数据格式的属性。
我们可以直接获取img对象的诸多属性,例如我们打印lena图的属性,具体如下:
# -*- coding: utf-8 -*- import numpy as npimport cv2# 导入一张图像 模式为彩色图片img = cv2.imread('lena.jpg', cv2.IMREAD_COLOR)print("================打印图像的属性================")print("图像对象的类型 {}".format(type(img)))print(img.shape)print("图像宽度: {} pixels".format(img.shape[1]))print("图像高度: {} pixels".format(img.shape[0]))print("通道: {}".format(img.shape[2]))print("图像分辨率: {}".format(img.size))print("数据类型: {}".format(img.dtype))123456789101112131415复制代码
输出结果:
================打印图像的属性================图像对象的类型 (256, 256, 3)图像宽度: 256 pixels图像高度: 256 pixels通道: 3图像分辨率: 196608数据类型: uint812345678复制代码有时候我们也可以偷懒,如果我们想创建与另外一个图像尺寸相同的画布的时候,我们可以使用np.zeros_like
canvas_black = np.zeros_like(img)1复制代码创建空白画布创建空白画布的函数如下:
def InitCanvas(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") canvas[:] = color return canvas1234复制代码调用的时候传入图像的宽度、高度和画布的颜色。例如创建一个800*600 颜色为纯黑色的画布:
canvas = InitCanvas(800, 600, color=(255,255,255))1复制代码创建空白画布的完整代码如下:
'''初始化画布'''import cv2import numpy as npdef init_canvas(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") canvas[:] = color return canvascanvas = init_canvas(200, 200, color=(125, 40, 255))cv2.imshow('canvas', canvas)cv2.waitKey(0)cv2.destroyAllWindows()1234567891011121314151617复制代码效果展示:
初始化白色的画布
白色的画布, 因为比较简单,而且三个通道的值都相同。
ps: 其实灰色的图片(GRAY2BGR),三个通道的值都相同。
那么我们创建一个全都是1的矩阵,然后乘上某个数值,问题是不是就解决了。
我们需要用到np.ones 函数
# 初始化一个空画布 300×300 三通道 背景色为白色 canvas_white = np.ones((300, 300, 3), dtype="uint8")12复制代码接下来, 需要乘上一个整数,255 (你可以填入0-255的任意值)
canvas_white *= 2551复制代码这种运算称之为 全局乘法 。
具体代码如下:
import cv2import numpy as npcanvas_white = np.ones((300, 300, 3), dtype="uint8")canvas_white *= 255cv2.imshow('canvas', canvas_white)cv2.waitKey(0)cv2.destroyAllWindows()1234567复制代码创建的白色画布如下:
初始化彩色的画布利用cv2的内置方法merge与split
我们初始化BGR的图片canvas_white 之后将原来的图片进行通道分离,之后分别乘上BGR三个通道的整数值,然后将三个通道合并在一起,就得到我们想要的彩图纯色背景。
那通道的分离我们需要用到的函数是cv2.split(img).
# 将原来的三个通道抽离出来, 分别乘上各个通道的值(channel_b, channel_g, channel_r) = cv2.split(canvas)12复制代码channel_b 蓝色通道,channel_g 绿色通道,channel_r 红色通道,都是二维的ndarray对象。
我们指定一种颜色,例如 color = (100, 20, 50))
注意:我们这里的颜色指的BGR格式
也就是
B -> 100G -> 20R -> 50
接下来我们分别将其乘上对应的值.
# 颜色的值与个通道的全1矩阵相乘channel_b *= color[0]channel_g *= color[1]channel_r *= color[2]1234复制代码接下来我们将三个通道重新合并,需要用到的函数是cv2.merge
cv2.merge([channel_b, channel_g, channel_r])1复制代码注意:三个通道的矩阵以list [] 的方式传入merge函数.
综合起来,就是我们的第一个初始化彩色背景的函数:
# 初始化一个彩色的画布 - cv2版本def init_canvas(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") # 将原来的三个通道抽离出来, 分别乘上各个通道的值 (channel_b, channel_g, channel_r) = cv2.split(canvas) # 颜色的值与个通道的全1矩阵相乘 channel_b *= color[0] channel_g *= color[1] channel_r *= color[2] # cv.merge 合并三个通道的值 return cv2.merge([channel_b, channel_g, channel_r])12345678910111213复制代码具体实现代码如下:
'''初始化画布'''import cv2import numpy as np# 初始化一个彩色的画布 - cv2版本def init_canvas(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") # 将原来的三个通道抽离出来, 分别乘上各个通道的值 (channel_b, channel_g, channel_r) = cv2.split(canvas) # 颜色的值与个通道的全1矩阵相乘 channel_b *= color[0] channel_g *= color[1] channel_r *= color[2] # cv.merge 合并三个通道的值 return cv2.merge([channel_b, channel_g, channel_r])canvas = init_canvas(200, 200, color=(125, 100, 255))cv2.imshow('canvas', canvas)cv2.waitKey(0)cv2.destroyAllWindows()1234567891011121314151617181920212223242526复制代码运行效果:
注意:此函数使用 cv2.split 非常耗时 所以只有在需要的时候才能做到。 否则用Numpy索引。
利用numpy内置的索引使用numpy原生的方法, 性能会比opencv中的要好。我们直接使用numpy的ndarray的索引的方法。
例如 canvas[:,:,0] 选中的是所有行,所有列,像素元素的第一个值,也就是,所有B通道的值。
然后对其进行赋值:
canvas[:,:,0] = color[0]1复制代码完整版本的函数如下,B/G/R通道分别进行赋值:
def init_canvas(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") # Blue canvas[:,:,0] = color[0] # Green canvas[:,:,1] = color[1] # Red canvas[:,:,2] = color[2] return canvas12345678910复制代码具体实现代码如下:
'''初始化画布'''import cv2import numpy as npdef init_canvas(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") # Blue canvas[:,:,0] = color[0] # Green canvas[:,:,1] = color[1] # Red canvas[:,:,2] = color[2] return canvascanvas = init_canvas(200, 200, color=(125, 100, 255))cv2.imshow('canvas', canvas)cv2.waitKey(0)cv2.destroyAllWindows()1234567891011121314151617181920212223复制代码运行实现的效果和第一种方法一样:
实际上我们还有更快的方法, 可以实现这个功能, 这就需要你熟练掌握Numpy的使用技巧.
我们可以直接赋值color
canvas[:] = color1复制代码完整实现过程如下:
'''初始化画布'''import cv2import numpy as npdef init_canvas(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") canvas[:] = color return canvascanvas = init_canvas(200, 200, color=(125, 40, 255))cv2.imshow('canvas', canvas)cv2.waitKey(0)cv2.destroyAllWindows()1234567891011121314151617复制代码运行的效果:
综合实验-初始化背景
在这个综合实验里会分别用上述的方法,创建黑色背景,白色背景,彩色背景。
具体代码如下:
'''初始化一个空白的画布并指定画布的颜色'''import cv2import numpy as np# 初始化一个空画布 300×300 三通道 背景色为黑色 canvas_black = np.zeros((300, 300, 3), dtype="uint8")cv2.imshow("canvas_black", canvas_black)# 初始化一个空画布 300×300 三通道 背景色为白色 canvas_white = np.ones((300, 300, 3), dtype="uint8")canvas_white *= 255cv2.imshow("canvas_white", canvas_white)'''初始化一个彩色的画布 - cv2版本此函数使用 cv2.split 非常耗时 所以只有在需要的时候才能做到。 否则用Numpy索引。'''def InitCanvasV1(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") # 将原来的三个通道抽离出来, 分别乘上各个通道的值 (channel_b, channel_g, channel_r) = cv2.split(canvas) # 颜色的值与个通道的全1矩阵相乘 channel_b *= color[0] channel_g *= color[1] channel_r *= color[2] # cv.merge 合并三个通道的值 return cv2.merge([channel_b, channel_g, channel_r])'''初始化一个彩色的画布 - numpy版本使用numpy的索引 赋值'''def InitCanvasV2(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") # Blue canvas[:,:,0] = color[0] # Green canvas[:,:,1] = color[1] # Red canvas[:,:,2] = color[2] return canvas'''初始化终极版本熟练掌握 numpy 才可以提高工作效率哦'''def InitCanvasV3(width, height, color=(255, 255, 255)): canvas = np.ones((height, width, 3), dtype="uint8") canvas[:] = color return canvas# 初始化一个彩色的画布canvas_color = InitCanvasV2(300, 300, color=(100, 20, 50))cv2.imshow("canvas_color", canvas_color)# 等待e键按下 关闭所有窗口while cv2.waitKey(0) != ord('e'): continuecv2.destroyAllWindows()12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970复制代码运行结果:
最后多说一句,小编是一名python开发工程师,这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以关注小编,并私信“01”领取。
思路:
1. 确定好需要画的图。
2. 创建一个画布,用来画你需要的图。
(1)画布大小,可以使用默认大小,也可以自定义画布大小。
(2)画布背景色bgcolor()。
(3)确定起点位置。
3. 画笔的设置。
(1)画笔的大小,颜色。
(2)画笔运行属性。
二、定义画布参数
import turtle as t
t.screensize(width = None,heigh = None,bg = None) #以像素为单位,参数分别为画布的宽,高,背景色
t.screensize() #返回默认大小(400,300)
t.Screen() #也是表示默认画布大小,注意S大写
t.setup(w=0.5,h=0.75,startx=None,starty=None) #w,h为整数是表示像素,为小数时表示占据电脑屏幕的比例
#startx,starty坐标表示矩形窗口左上角顶点的位置,默认为屏幕中心位置
三、定义画笔
1、画笔的状态
在画布上默认有一个坐标原点为画布中心的坐标轴,坐标原点上有一只面朝x轴正方向小乌龟。这里我们描述小乌龟时使用了两个词语:坐标原点(位置),面朝x轴正方向(方向),turtle绘图中,就是使用位置方向描述小乌龟(画笔)的状态。
2、画笔的属性
画笔(画笔的属性,颜色、画线的宽度)
(1)turtle.pensize():设置画笔的宽度;
(2)turtle.pencolor():没有参数传入,返回当前画笔颜色,传入参数设置画笔颜色,可以是字符串如"green","red",也可以是RGB 3元组;
>>> pencolor(brown)
>>> tup = (0.2, 0.8, 0.55)
>>> pencolor(tup)
>>> pencolor()
#33cc8c
(3)turtle.speed(speed):设置画笔移动速度,画笔绘制的速度范围[0,10]整数,数字越大越快。
相关推荐:《Python入门教程》
3、绘图命令
操纵海龟绘图有着许多的命令,这些命令可以划分为3种:一种为运动命令,一种为画笔控制命令,还有一种是全局控制命令。
(1)画笔运动命令:
(2)画笔控制命令:
(3)全局控制命令:
四、命令详解
turtle.circle(radius, extent=None, steps=None)
描述:以给定半径画圆
参数:
radius(半径);半径为正(负),表示圆心在画笔的左边(右边)画圆;
extent(弧度) (optional);
steps (optional) (做半径为radius的圆的内切正多边形,多边形边数为steps);
举例:
circle(50) # 整圆;
circle(50,steps=3) # 三角形;
circle(120, 180) # 半圆
五、绘图举例
(1)菱形太阳花
import turtle as t #turtle库是python的内部库,直接import使用即可
def draw_diamond(turt):
for i in range(1,3):
turt.forward(100) #向前走100步
希望我的回答对你有帮助
1、首先在python软件中,创建一个响应鼠标的自定义函数,当鼠标在画布上面点击一下,就画一个圆。
2、创建一个画布,背景是白色:img=np.ones((365,500,3),np.uint8)*255。
3、然后创建一个窗口:cv2.namedWindow(image)。当鼠标在这个窗口里面的时候,上面的自定义函数会响应鼠标。
4、开始一个while循环,每次在image窗口里面点击鼠标,就会画一个圆。
5、执行程序之后,在画布上随机的点击鼠标,就可以得到彩色的圆。