第一篇——简单图片处理以及简易的画图工具实现
以下的实现过程参考OpenCV官网教程, 详情移步OpenCV官网进行查阅
- 读取和写入图片
- 视频处理以及摄像头图像的捕获和保存
- 使用鼠标事件实现简易的画图功能
- color bar的使用
- 画图工具的实现
1. 读取和写入图片
这里主要是用到了imread函数和imwrite函数。这两个函数均可以通过导入openCV包来使用。
from cv2 import *
# read pic
img = imread('test.jpg')
# show pic
imshow('image', img)
# save pic
imwrite('test2.jpg', img)
在执行的时候会发现显示的图片很快就消失了,这时需要使用一个函数让程序保持等待状态。
waitKey(0)
上面是对于任意的一个输入都会结束,如果想让程序在给定的输入下跳出,这时候需要编写一个循环来不断监听键盘事件,并判断输出是否是预期的键值。
while(1):
cv2.imshow('image',img)
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
elif k == ord('l'):
drawing_mode = 0
elif k == ord('r'):
drawing_mode = 1
这里的k保存的是监听到的键值的ascall码,由于不同计算机可能使用的键盘编码不同,所以这里通过一个位运算取最低的一个字节进行判断。值为27表示输入的是esc,其他字符可以通过使用ord函数来获取其对应的编码值。
一般说在不需要浏览窗口的时候需要将窗口进行销毁。具体方法如下:
destroyAllWindows()
2. 视频处理以及摄像头图像的捕获和保存
cv2库中提供了一个可以获取摄像头或者是从给定视频文件中读取数据的函数:VideoCapture。该函数接受一个参数,如果输入参数为0,表示从摄像头总获取数据,如果是一个字符串,则将该字符串解释为视频文件的路径进行读取。
对于一个视频文件的处理就是对一个视频的每个帧进行处理。
可以使用一个简单循环操作来读取数据,那么如何判断一个视频文件是否已经读取结束呢?
对于一个普通文件来说可以使用如下一个函数进行判断:
# cap is the data we read from either file or camera
while cap.isOpened():
#process the data here
blablabla...
而对于一个处理camera的程序,则只需要通过上文中一个键盘监听事件就可以完成。处理过程如下:
# you can also get the frame from the existed file
# cap2 = VideoCapture(filePath)
# also if you want to save the video you can define a buffer for output like what is shown below
# out = cv2.VideoWriter('output.avi',source, 20.0, (640,480))
# get frame from the computer camera
cap = VideoCapture(0)
while True:
# get a frame
ret, frame = cap.read()
# show the frame
imshow('image', frame)
# exit when receiving an 'q' input
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# release the frame
cap.release()
destroyAllWindows()
值得注意的是,这里在处理完camera或者一个视频file的时候需要将读取的变量释放,这里是使用了一个release函数来实现。
3. 使用鼠标事件实现简易的画图功能
opencv库中提供了很多键盘事件响应。他们通过一些关键字进行标识。这里可以通过在命令行键入如下代码展示所有内嵌的事件。
具体使用步骤如下:
step 1:将处理函数与cv2中鼠标监听函数进行绑定
cv2.setMouseCallback('image',draw_circle)
step 2:编写处理函数
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)
简单来说就是通过类似于if的条件语句来判断是否有监听到的事件,然后进行相应处理。这里需要注意到的是,处理函数中的参数是自动传递的,event表示响应的时间,x, y表示当前鼠标的位置,后面是一些标志位,这里我们暂时还用不到,想要知道其详细用法的同学可以通过查找opencv的官方文档进行查阅。
在执行处理函数的时候,我们可以添加一些简单的画图函数。
# create a empty frame (0 means all black)
img = zeros((512,512,3), uint8)
# Draw a diagonal blue line with thickness of 5 px
# function line parameter: (begin, end, color, size)
cv2.line(img,(0,0),(511,511),(255,0,0),5)
cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
cv2.circle(img, (255, 255), 60, (0, 0, 255), 6)
# other drawing function share the same feature, look for the document if necessary
# add some text on the pic
# define the font style
font = cv2.FONT_HERSHEY_SIMPLEX
# add text
cv2.putText(img,'put some text',(10,500), font, 2,(255,255,255),2,cv2.LINE_AA)
首先需要创建一个空白的画图板,这里用到了numpy库中的三维矩阵来实现。用的时候需要导入该库:
from numpy import *
上面完整的程序中给出了三个画图的函数,line, rectangle,circle。分别对应画线,画矩形,画圆,当然opencv库中还提供了一些更为复杂的画图函数,这里不一一进行列举。最后还有一个添加文本的函数:putText
使用方法都类似,这里举rectangle函数为例。该函数接受5个参数,分别是:待处理的图片,起点坐标,终点坐标,颜色,线粗细。对于最后一个参数来说,如果接受的是-1则表示完全填充。
4. color bar的使用
这个工具主要用来调制颜色,其核心就是通过使用一个GUI工具来产生一个0-255的数值,在通过读取这个数值并将其转换成对应的RGB的像素值。
核心函数是createTrackbar和getTrackbarPos,前者用来定义一个调色板,后者获取其值。
具体使用方法如下:
def nothing(x):
pass
# Create a black image, a window
img = zeros((300,512,3), uint8)
cv2.namedWindow('image')
# create trackbars for color change
cv2.createTrackbar('R','image',0,255,nothing)
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)
def getColor():
# get current positions of four trackbars
r = cv2.getTrackbarPos('R','image')
g = cv2.getTrackbarPos('G','image')
b = cv2.getTrackbarPos('B','image')
# return the color
return (r, g, b)
对于每个createTrackbar都对应一个响应函数,这里我们将其设置为一个空函数,需要注意的是,这个函数接受一个参数,所以在定义的时候需要添加一个参数才行。
5. 画图工具的实现
通过组合使用上述的几种函数,可以构建一个简易的画图工具。
代码如下:
def nothing(x):
pass
# Create a black image, a window
img = zeros((300,512,3), uint8)
cv2.namedWindow('image')
# create trackbars for color change
cv2.createTrackbar('R','image',0,255,nothing)
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)
def getColor():
# get current positions of four trackbars
r = cv2.getTrackbarPos('R','image')
g = cv2.getTrackbarPos('G','image')
b = cv2.getTrackbarPos('B','image')
# return the color
return (r, g, b)
def paint(event,x,y,flags,param):
global begin_x, begin_y,painting, drawing_mode
# if the mouse is pressed down
if event == EVENT_LBUTTONDOWN:
painting = True
begin_x, begin_y = x, y
# if the mouse is moving
elif event == EVENT_MOUSEMOVE:
if painting == True:
print(drawing_mode)
if drawing_mode == 0:
print('as')
circle(img, (x, y), 3, getColor(), -1)
elif drawing_mode == 1:
rectangle(img, (begin_x, begin_y), (x, y), getColor(), 3, -1)
else:
line(img, (begin_x, begin_y), (x, y), getColor(), 3)
# if the mouse is not pressed
elif event == EVENT_LBUTTONUP:
painting = False
def painter():
global drawing_mode
setMouseCallback('image',paint)
while(1):
cv2.imshow('image',img)
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
elif k == ord('l'):
drawing_mode = 0
# change mode to drawing rectangle
elif k == ord('r'):
drawing_mode = 1
cv2.destroyAllWindows()
painting = False
begin_x, begin_y = -1, -1
drawing_mode = 0
painter()
cv2.destroyAllWindows()
执行效果如下:
总结
总的来说opencv中对于处理图像而言与matlab处理时十分类似的,如果你曾学习过matlab的话,你将会发现很多相似的地方。
下面给出本次所有程序的完整代码:
from numpy import *
from cv2 import *
def getCamera():
# you can also get the frame from the existed file
# cap2 = VideoCapture(filePath)
# also if you want to save the video you can define a buffer for output like what is shown below
# out = cv2.VideoWriter('output.avi',source, 20.0, (640,480))
# get frame from the computer camera
cap = VideoCapture(0)
while(true):
# get a frame
ret, frame = cap.read()
# show the frame
imshow('image', frame)
# exit when receiving an 'q' input
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# release the frame
cap.release()
destroyAllWindows()
def pic():
# read pic
img = imread('test.jpg')
# show pic
imshow('image', img)
# save pic
imwrite('test2.jpg', img)
# get the shape of the pic
print(shape(img))
# stay alive until get an external interrupt
waitKey(0)
# destory the opened window
destroyAllWindows()
def drawPic():
# create a empty frame (0 means all black)
img = zeros((512,512,3), uint8)
# Draw a diagonal blue line with thickness of 5 px
# function line parameter: (begin, end, color, size)
cv2.line(img,(0,0),(511,511),(255,0,0),5)
cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
cv2.circle(img, (255, 255), 60, (0, 0, 255), 6)
# other drawing function share the same feature, look for the document if necessary
# add some text on the pic
# define the font style
font = cv2.FONT_HERSHEY_SIMPLEX
# add text
cv2.putText(img,'put some text',(10,500), font, 2,(255,255,255),2,cv2.LINE_AA)
imshow('image', img)
waitKey(0)
destroyAllWindows()
# mouse callback function
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)
def draw():
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
ix,iy = -1,-1
while(1):
cv2.imshow('image',img)
k = cv2.waitKey(1) & 0xFF
if k == ord('m'):
mode = not mode
elif k == 27:
break
cv2.destroyAllWindows()
img = zeros((512,512,3), uint8)
drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
#----------------------------------------------------------------------------------
# design a painting tools
def nothing(x):
pass
# Create a black image, a window
img = zeros((300,512,3), uint8)
cv2.namedWindow('image')
# create trackbars for color change
cv2.createTrackbar('R','image',0,255,nothing)
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)
def getColor():
# get current positions of four trackbars
r = cv2.getTrackbarPos('R','image')
g = cv2.getTrackbarPos('G','image')
b = cv2.getTrackbarPos('B','image')
# return the color
return (r, g, b)
def paint(event,x,y,flags,param):
global begin_x, begin_y,painting, drawing_mode
# if the mouse is pressed down
if event == EVENT_LBUTTONDOWN:
painting = True
begin_x, begin_y = x, y
# if the mouse is moving
elif event == EVENT_MOUSEMOVE:
if painting == True:
print(drawing_mode)
if drawing_mode == 0:
print('as')
circle(img, (x, y), 3, getColor(), -1)
elif drawing_mode == 1:
rectangle(img, (begin_x, begin_y), (x, y), getColor(), 3, -1)
else:
line(img, (begin_x, begin_y), (x, y), getColor(), 3)
# if the mouse is not pressed
elif event == EVENT_LBUTTONUP:
painting = False
def painter():
global drawing_mode
setMouseCallback('image',paint)
while(1):
cv2.imshow('image',img)
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
elif k == ord('l'):
drawing_mode = 0
# change mode to drawing rectangle
elif k == ord('r'):
drawing_mode = 1
cv2.destroyAllWindows()
painting = False
begin_x, begin_y = -1, -1
drawing_mode = 0
painter()
cv2.destroyAllWindows()