参考:https://github.com/makelove/OpenCV-Python-Tutorial
ch01-关于OpenCV
opencv坐标系
关于图像坐标系与行列宽高的对应关系大致如下:
- row == height == Point.y
- col == width == Point.x
区分开矩阵 行列;图像x,y
图像x,y: 类似数学中的x,y坐标轴,x对应水平方向,y对应竖直方向,注意图像的原点在左上角,x表示图像的宽度变化(对应矩阵的列变化),y表示图像的高度变化(对应矩阵的行变化)
因此有: col == width == Point.x ;row == height == Point.y
图像坐标体系中的零点坐标为图片的左上角,X轴为图像矩形的上面那条水平线;Y轴为图像矩形左边的那条垂直线。
如果要获取图像坐标轴(x,y)对应的像素值
1、image.at(y, x) image为Mat
2、Point(x, y)
3、image[x,y] image为对应图像的矩阵
图像的通道数时n,则使用Mat::at(y, x)时,其y的范围依旧是0到image的height,而x的取值范围则是0到image的width乘以n,因为这个时候是有n个通道,所以每个像素需要占有n列。但是如果在同样的情况下,使用Mat::at(point)来访问的话,则这时候可以不用考虑通道的个数,因为你要赋值给获取Mat::at(point)的值时,都不是一个数字,而是一个对应的n维向量。
矩阵行列: 将图像转成对应的矩阵对应的格式[h,w,c],其中h为矩阵的行数对应图像的高度,w为矩阵的列数对应图像的宽度,c为图像的通道数
# -*- coding: utf-8 -*-
# @Time : 2017/7/28 23:13
# @Author : play4fun
# @File : OpenCV图像坐标系_test.py
# @Software: PyCharm
"""
OpenCV图像坐标系_test.py:
"""
# TODO
import numpy as np
import cv2
img = cv2.imread('../data/Lenna.png', cv2.IMREAD_UNCHANGED)
print('img.shape:', img.shape)
logo = cv2.imread('../data/opencv_logo.png', cv2.IMREAD_UNCHANGED)
logo = cv2.resize(logo, (20, 20))
print('logo.shape:', logo.shape)
butterfly= cv2.imread('../data/butterfly.jpg', cv2.IMREAD_UNCHANGED)
butterfly = cv2.resize(butterfly, (20, 20))
print('butterfly.shape:', butterfly.shape)
cv2.imshow('src', img)
cv2.moveWindow('src', 0, 0)
# read color values at position y, x
y = 100
x = 50
(b, g, r) = img[y, x]
# print color values to screen
print('bgr:',b,g,r)
#先行后列
#img[y:y+height,x:width]
img[100:100 + logo.shape[0], 300:300 + logo.shape[1]] = logo[:, :, 0:3]# 两张图片的shape不一样
# img[10:10+logo.shape[0],30:30+logo.shape[1],:]=logo[:,:,0:3]
img[300:300 + logo.shape[1], 100:100 + logo.shape[0]] = butterfly[:, :, 0:3]
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, text='col=width=X0,row=height-Y0', org=(0, 0), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2,bottomLeftOrigin=True) # text,
cv2.putText(img, text='col=width=X10,row=height-Y30', org=(10, 30), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2) # text,
cv2.putText(img, text='col=width=X100,row=height-Y300', org=(100, 300), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2) # text,
cv2.putText(img, text='col=width-X300,row=height-Y100', org=(300, 100), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2) # text,
cv2.imshow('img+logo', img)
cv2.imwrite('img_logo.jpg',img)
cv2.moveWindow('img+logo', x=img.shape[0], y=0)
cv2.waitKey(0)
ch02-安装OpenCV
安装 opencv-python
- virtualenv -p python3 .cv2
- source .cv2/bin/activate
- pip install opencv-python
- pip install matplotlib
- 验证 python -c “import cv2;print(cv2.version,cv2.doc,cv2.file)”
安装 opencv-contrib-python
强烈建议先卸载opencv-python
- pip uninstall opencv-python
- pip install opencv-contrib-python
- 验证 python -c “import cv2;print(cv2.version,cv2.doc,cv2.file)”
- 验证 python -c “import
- cv2;print(print(help(cv2.CascadeClassifier)))”
Windows安装Python版
进入http://www.lfd.uci.edu/~gohlke/pythonlibs下载
opencv_python‑3.3.1+contrib‑cp36‑cp36m‑win_amd64.whl (包含contrib模块)
打开cmd 切换到文件路径
pip install opencv_python‑3.3.1+contrib‑cp36‑cp36m‑win_amd64.whl
编译安装
参考:http://blog.csdn.net/wc781708249/article/details/78502807
ch03-相关教程及视频
《OpenCV-Python教程》,感觉很好 http://blog.csdn.net/sunny2038/article/category/904451
视频
ch04-图片
# -*- coding: utf-8 -*-
import numpy as np
import cv2
print(cv2.__version__)
# img = cv2.imread('messi5.jpg',cv2.IMREAD_COLOR)#读入一副彩色图像。图像的透明度会被忽略 默认参数。
# img = cv2.imread('messi5.jpg', cv2.IMREAD_GRAYSCALE)# Load an color image in grayscale 灰度
img = cv2.imread('messi5.jpg',cv2.IMREAD_UNCHANGED)#包括图像的 alpha 通道
img = cv2.resize(img, (640, 480))
# img.I
# AttributeError: 'numpy.ndarray' object has no attribute 'I'
#
rows,cols,ch=img.shape
print('行/高:',rows,'列/宽:',cols,'通道:',ch)
#图像的宽对应的是列数, 高对应的是行数。
cv2.namedWindow('image', cv2.WINDOW_NORMAL)#可以调整窗口大小
# cv2.namedWindow('image', cv2.WINDOW_AUTOSIZE)#自动调整
# cv2.namedWindow('image', cv2.WINDOW_KEEPRATIO)#保持图片比例
# cv2.resizeWindow('image', 200, 200) # 不起作用?
cv2.imshow('image', img)#窗口会自动调整为图像大小
# 按任意键退出
cv2.waitKey(0)#返回按键的 ASCII 码值
cv2.destroyAllWindows()
#
# cv2.imwrite('messigray.png', img)
ch05-视频
VideoCapture.py
# -*- coding: utf-8 -*-
"""
Created on Fri Jan 3 21:06:22 2014
@author: duan
"""
'''
注意 当你的程序报错时 你 先检查的是你的摄像头是否能够在其他程 序中正常工作 比如 linux 下的 Cheese 。
'''
import numpy as np
import cv2
cap = cv2.VideoCapture(0) # 一般的笔 本电脑 有内置摄像头。所以参数就是 0。你可以 设置成 1 或 者其他的来 择别的摄像头
'''
你可以使用函数 cap.get(propId) 来获得 的一些参数信息。
propId 可以是 0 到 18 之 的任何整数。
其中的一些值可以使用 cap.set(propId,value) 来修改 value 就是 你想 置成的新值。
例如 我可以使用 cap.get(3) cv2.CAP_PROP_FRAME_WIDTH和 cap.get(4) cv2.CAP_PROP_FRAME_HEIGHT来查看每一帧的宽和高。
默认情况下得到的值是 640X480。但是我可以使用 ret=cap.set(3,320) 和 ret=cap.set(4,240) 来把宽和高改成 320X240。
'''
# ret=cap.set(3,320)
# ret=cap.set(4,240)
# ret = cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)#避免计算量过大
# ret = cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 270)#
#等比缩放
frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)#4 ,720
frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)#3 ,1280
frame_height=int(480/frame_width*frame_height)#270
ret = cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)#高
ret = cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)
# while (True):
while cap.isOpened(): # 检查是否成功初始化,否则就 使用函数 cap.open()
# Capture frame-by-frame
ret, frame = cap.read() # ret 返回一个布尔值 True/False
# print('frame shape:',frame.shape)#(720, 1280, 3)
frame = cv2.flip(frame, flipCode=1) # 左右翻转,使用笔记本电脑摄像头才有用。
# flipCode:翻转方向:1:水平翻转;0:垂直翻转;-1:水平垂直翻转
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame', gray)
cv2.setWindowTitle('frame', 'COLOR_BGR2GRAY')
# Property=cv2.getWindowProperty('frame',0)#无用
# if cv2.waitKey(1) & 0xFF == ord('q'):#不行
# break
key = cv2.waitKey(delay=10)
if key == ord("q"):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
VideoPlay.py
import numpy as np
import cv2
cap = cv2.VideoCapture('../data/vtest.avi')
# cap = cv2.VideoCapture('output.avi')
# cap = cv2.VideoCapture('Minions_banana.mp4')
# 帧率
fps = cap.get(cv2.CAP_PROP_FPS) # 25.0
print("Frames per second using video.get(cv2.CAP_PROP_FPS) : {0}".format(fps))
# 总共有多少帧
num_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
print('共有', num_frames, '帧')
#
frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # cap.get(3)
frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # cap.get(4)
print('高:', frame_height, '宽:', frame_width)
FRAME_NOW = cap.get(cv2.CAP_PROP_POS_FRAMES) # 第0帧
print('当前帧数', FRAME_NOW) # 当前帧数 0.0
# 读取指定帧,对视频文件才有效,对摄像头无效??
frame_no = 121
cap.set(1, frame_no) # Where frame_no is the frame you want
ret, frame = cap.read() # Read the frame
cv2.imshow('frame_no'+str(frame_no), frame)
FRAME_NOW = cap.get(cv2.CAP_PROP_POS_FRAMES)
print('当前帧数', FRAME_NOW) # 当前帧数 122.0
while cap.isOpened():
ret, frame = cap.read()
FRAME_NOW = cap.get(cv2.CAP_PROP_POS_FRAMES) # 当前帧数
print('当前帧数', FRAME_NOW)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame', gray)
key = cv2.waitKey(1)
if key == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
VideoWriter.py
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
width = 640
ret = cap.set(3, width)
height = 480
ret = cap.set(4, height)
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID') # opencv 3.0
# Error: 'module' object has no attribute 'VideoWriter_fourcc'
# fourcc=cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
#jpeg,h263,'m', 'p', '4', 'v'
#
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (width, height))
while cap.isOpened():
ret, frame = cap.read()
if ret is True:
frame = cv2.resize(frame, (640, 480))
# write the flipped frame
out.write(frame)
cv2.imshow('frame', frame)
else:
break
key = cv2.waitKey(1)
if key == ord("q"):
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
two_camera.py
# -*- coding: utf-8 -*-
# @Time : 2017/8/15 00:19
# @Author : play4fun
# @File : two_camera.py
# @Software: PyCharm
"""
two_camera.py:
"""
import cv2
import numpy as np
cap0 = cv2.VideoCapture(0)
cap1 = cv2.VideoCapture(1)
ret = cap0.set(3, 320)
ret = cap0.set(4, 240)
ret = cap1.set(3, 320)
ret = cap1.set(4, 240)
while cap0.isOpened() and cap1.isOpened():
ret0, frame0 = cap0.read()
ret1, frame1 = cap1.read()
if ret0:
cv2.imshow('frame0', frame0)
cv2.setWindowTitle('frame0','On Top')
if ret1:
cv2.imshow('frame1', frame1)
# cv2.moveWindow('frame1', x=frame0.shape[1], y=0)
cv2.moveWindow('frame1', x=320, y=40)
key = cv2.waitKey(delay=2)
if key == ord("q"):
break
# When everything done, release the capture
cap0.release()
cap1.release()
cv2.destroyAllWindows()
ch06-绘图函数
draw.py
# -*- coding: utf-8 -*-
import numpy as np
import cv2
'''
• img: 你想 绘制图形的 幅图像。
• color: 形状的颜色。以RGB为例 需要传入一个元组 例如 255,0,0
代表蓝色。对于灰度图只需要传入灰度值。
• thickness 线条的粗细。如果给一个闭合图形 置为 -1 那么这个图形
就会被填充。 默认值是 1.
• linetype 线条的类型, 8 连接,抗锯齿等。 默认情况是8 连接。cv2.LINE_AA
为抗锯齿 这样看起来会非常平滑。
'''
# Create a black image
img = np.zeros((512, 512, 3), np.uint8)
# Draw a diagonal blue line with thickness of 5 px
cv2.line(img, pt1=(0, 0), pt2=(511, 511), color=(255, 0, 0), thickness=5) # pt1, pt2, color, thickness=
# cv2.polylines() 可以 用来画很多条线。只需要把想 画的线放在一 个列表中, 将 列表传给函数就可以了。每条线 会被独立绘制。 这会比用 cv2.line() 一条一条的绘制 要快一些。
# cv2.polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
cv2.arrowedLine(img,pt1=(21, 13), pt2=(151, 401), color=(255, 0, 0), thickness=5)
cv2.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)
cv2.circle(img, center=(447, 63), radius=63, color=(0, 0, 255), thickness=-1) # center, radius, color, thickness=None
# 一个参数是中心点的位置坐标。 下一个参数是长轴和短轴的长度。椭圆沿逆时针方向旋转的角度。
# 椭圆弧演顺时针方向起始的角度和结束角度 如果是 0 很 360 就是整个椭圆
cv2.ellipse(img, center=(256, 256), axes=(100, 50), angle=0, startAngle=0, endAngle=180, color=255,
thickness=-1) # center, axes, angle, startAngle, endAngle, color, thickness=
pts = np.array([[10, 5], [20, 30], [70, 20], [50, 10]], np.int32)
pts = pts.reshape((-1, 1, 2))
# 这里 reshape 的第一个参数为-1, 表明这一维的长度是根据后面的维度的计算出来的。
# 注意 如果第三个参数是 False 我们得到的多边形是不闭合的 ,首 尾不相 连 。
font = cv2.FONT_HERSHEY_SIMPLEX
#org :Bottom-left corner of the text string in the image.左下角
#或使用 bottomLeftOrigin=True,文字会上下颠倒
cv2.putText(img, text='bottomLeftOrigin', org=(10, 400), fontFace=font, fontScale=1, color=(255, 255, 255), thickness=1,bottomLeftOrigin=True)#text, org, fontFace, fontScale, color, thickness=
cv2.putText(img, text='OpenCV', org=(10, 500), fontFace=font, fontScale=4, color=(255, 255, 255), thickness=2)#text, org, fontFace, fontScale, color, thickness=
# 所有的绘图函数的返回值都是 None ,所以不能使用 img = cv2.line(img,(0,0),(5
winname = 'example'
cv2.namedWindow(winname, 0)
cv2.imshow(winname, img)
cv2.imwrite("example.png", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
draw_opencv_logo.py
# -*- coding: utf-8 -*-
# @Time : 2017/7/11 下午7:07
# @Author : play4fun
# @File : draw_opencv_logo.py
# @Software: PyCharm
"""
draw_opencv_logo.py:Try to create the logo of OpenCV using drawing functions available in OpenCV.
"""
import numpy as np
import cv2 # 3.0.0-dev
import math
r1 = 70
r2 = 30
ang = 60
d = 170
h = int(d / 2 * math.sqrt(3))
dot_red = (256, 128)
dot_green = (int(dot_red[0] - d / 2), dot_red[1] + h)
dot_blue = (int(dot_red[0] + d / 2), dot_red[1] + h)
# tan = float(dot_red[0]-dot_green[0])/(dot_green[1]-dot_red[0])
# ang = math.atan(tan)/math.pi*180
red = (0, 0, 255)
green = (0, 255, 0)
blue = (255, 0, 0)
black = (0, 0, 0)
full = -1
img = np.zeros((512, 512, 3), np.uint8)
# img = np.ones((512, 512, 3), np.uint8)
cv2.circle(img, dot_red, r1, red, full)
cv2.circle(img, dot_green, r1, green, full)
cv2.circle(img, dot_blue, r1, blue, full)
cv2.circle(img, dot_red, r2, black, full)
cv2.circle(img, dot_green, r2, black, full)
cv2.circle(img, dot_blue, r2, black, full)
cv2.ellipse(img, dot_red, (r1, r1), ang, 0, ang, black, full)
cv2.ellipse(img, dot_green, (r1, r1), 360 - ang, 0, ang, black, full)
cv2.ellipse(img, dot_blue, (r1, r1), 360 - 2 * ang, ang, 0, black, full)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, text='OpenCV', org=(15, 450), fontFace=font, fontScale=4, color=(255, 255, 255), thickness=10)#text,
cv2.imwrite("opencv_logo.png", img)
# cv2.imwrite("opencv_logo2.png", img)
Drawing_UTF-8_strings.py
# -*- coding: utf-8 -*-
# @Time : 2017/7/23 下午9:11
# @Author : play4fun
# @File : Drawing_UTF-8_strings.py
# @Software: PyCharm
"""
Drawing_UTF-8_strings.py:
https://fireant.github.io/misc/2017/01/28/ttf-opencv.html
"""
import cv2
import numpy as np
img = np.zeros((100, 300, 3), dtype=np.uint8)
ft = cv2.freetype.createFreeType2() # 需要安装freetype模块 cv2' has no attribute 'freetype'
# ft.loadFontData(fontFileName='Ubuntu-R.ttf',id=0)
# ft.loadFontData(fontFileName='/usr/share/fonts/truetype/freefont/FreeSans.ttf',id=0)#不支持中文
# ft.loadFontData(fontFileName='/usr/share/fonts-droid/truetype/DroidSansFallback.ttf',id=0)#树莓派,搞定
#sudo apt-get install ttf-wqy-zenhei #安装字体
ft.loadFontData(fontFileName='/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc', id=0) # 文泉驿的开源中文字体
ft.putText(img=img,
# text='Quick Fox',
text='你好中文',
org=(15, 70),
fontHeight=60,
color=(255, 255, 255),
thickness=-1,
line_type=cv2.LINE_AA,
bottomLeftOrigin=True)
# cv2.imwrite('freetype.png', img)
cv2.imshow('freetype', img)
cv2.waitKey(0)
画圆圈.py
# -*- coding: utf-8 -*-
# @Time : 2017/7/17 下午12:03
# @Author : play4fun
# @File : 画圆圈.py
# @Software: PyCharm
"""
画圆圈.py:随机覆盖,不同颜色,
"""
from time import sleep
import cv2
import numpy as np
def click_event(event, x, y, flags, param):
'''
用左键点击屏幕,打印坐标
:param event:
:param x:
:param y:
:param flags:
:param param:
:return:
'''
if event == cv2.EVENT_LBUTTONDOWN:
print(x, y, flags, param)
cv2.namedWindow('Canvas', cv2.WINDOW_GUI_EXPANDED)
cv2.setMouseCallback("Canvas", click_event)
canvas = np.zeros((300, 300, 3), dtype="uint8")
while True:
try:
for i in range(0, 25):
radius = np.random.randint(5, high=200)
color = np.random.randint(0, high=256, size=(3,)).tolist()
pt = np.random.randint(0, high=300, size=(2,))
cv2.circle(canvas, tuple(pt), radius, color, -1)
cv2.imshow("Canvas", canvas)
key = cv2.waitKey(1000) # 等待1秒
if key == ord('q'):
break
else:
# sleep(1)
continue
except KeyboardInterrupt as e:
print('KeyboardInterrupt', e)
finally:
cv2.imwrite('random-circles2.jpg', canvas)
ch07-把鼠标当画笔
draw_circle_rectangle.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
# 当鼠标按下时变为 True
drawing = False
# 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
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
# 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
if drawing is True:
if mode is True:
cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
# 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
# 下面注释掉的代码是起始点为圆心,起点到终点为半径的
# r = int(np.sqrt((x - ix) ** 2 + (y - iy) ** 2))
# cv2.circle(img, (x, y), r, (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)
mode = False
cv2.namedWindow('image', 0)
cv2.setMouseCallback('image', draw_circle)
while True:
cv2.imshow('image', img)
k = cv2.waitKey(1) # & 0xFF
if k == ord('m'):
mode = not mode
elif k == ord("q"):
break
MouseCallback.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
# mouse callback function
def draw_circle(event, x, y, flags, param): # 只用做一件事:在双击过的地方绘 制一个圆圈。
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.circle(img, (x, y), 100, (255, 0, 0), -1)
# 创建图像与窗口并将窗口与回调函数绑定
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.setMouseCallback('image', draw_circle)
while True:
cv2.imshow('image', img)
# if cv2.waitKey(20) & 0xFF == 27:
# break
key = cv2.waitKey(1)
if key == ord("q"):
break
cv2.destroyAllWindows()
鼠标左右键回调函数.py
# -*- coding: utf-8 -*-
# @Time : 2017/7/17 下午6:19
# @Author : play4fun
# @File : 鼠标左右键回调函数.py
# @Software: PyCharm
"""
鼠标左右键回调函数.py:
"""
import cv2
def click_event(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
print(x, y)
if event == cv2.EVENT_RBUTTONDOWN:
red = img[y, x, 2]
blue = img[y, x, 0]
green = img[y, x, 1]
print(red, green, blue)
strRGB = str(red) + "," + str(green) + "," + str(blue)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, strRGB, (x, y), font, 1, (255, 255, 255), 2)
cv2.imshow('original', img)
img = cv2.imread('../data/messi5.jpg')
cv2.imshow('original', img)
cv2.setMouseCallback("original", click_event)
cv2.waitKey(0)
cv2.imwrite('putText.jpg',img)
cv2.destroyAllWindows()
ch08-用滑动条做调色板
createTrackbar.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
def nothing(x):
pass
# Create a black image, a window
img = np.zeros((300, 512, 3), np.uint8)
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
# 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)
# create switch for ON/OFF functionality
switch = '0 : OFF \n1 : ON'
cv2.createTrackbar(switch, 'image', 0, 1, nothing)
# 只有当 转换按钮 指向 ON 时 滑动条的滑动才有用,否则窗户 都是黑的。
while True:
# get current positions of four trackbars
r = cv2.getTrackbarPos('R', 'image')
g = cv2.getTrackbarPos('G', 'image')
b = cv2.getTrackbarPos('B', 'image')
s = cv2.getTrackbarPos(switch, 'image') # 另外一个重要应用就是用作转换按钮
if s == 0:
img[:] = 0
else:
img[:] = [b, g, r]
cv2.imshow('image', img)
k = cv2.waitKey(1) # & 0xFF
if k == ord("q"):
break
cv2.destroyAllWindows()
Trackbar_draw.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
def nothing(x):
pass
# 当鼠标按下时变为 True
drawing = False
# 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
ix, iy = -1, -1
'''
cv2.getTrackbarPos() 函数的第一个参数是滑动条的名字
第二个参数 是滑动条被放置窗口的名字
第三个参数是滑动条的默认位置。
第四个参数是滑动条的最大值
第五个函数是回调函数, 每次滑动条的滑动都会调用回调函 数。
回调函数通常都会含有一个默认参数 就是滑动条的位置
'''
# 创建回调函数
def draw_circle(event, x, y, flags, param):
r = cv2.getTrackbarPos('R', 'image')
g = cv2.getTrackbarPos('G', 'image')
b = cv2.getTrackbarPos('B', 'image')
color = (b, g, r)
global ix, iy, drawing, mode
# 当按下左键是返回起始位置坐标
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
# 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
if drawing is True:
if mode is True:
cv2.rectangle(img, (ix, iy), (x, y), color, -1)
else:
# 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
cv2.circle(img, (x, y), 3, color, -1)
# 下面注释掉的代码是起始点为圆心,起点到终点为半径的
# r=int(np.sqrt((x-ix)**2+(y-iy)**2))
# cv2.circle(img,(x,y),r,(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)
mode = False
cv2.namedWindow('image')
cv2.createTrackbar('R', 'image', 0, 255, nothing)
cv2.createTrackbar('G', 'image', 0, 255, nothing)
cv2.createTrackbar('B', 'image', 0, 255, nothing)
cv2.setMouseCallback('image', draw_circle)
while True:
cv2.imshow('image', img)
k = cv2.waitKey(1) # & 0xFF
if k == ord('m'):
mode = not mode
elif k == ord("q"):
break
ch09-图像的基础操作
9.img_roi.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
'''
例如我们 检测一副图像中 眼睛的位置 我们 先应该在图像中找到脸 再在脸的区域中找眼睛
而不是 直接在一幅图像中搜索。这样会提高程序的准确性和性能。
'''
img=cv2.imread('../data/messi5.jpg')
ball=img[280:340,330:390]
img[273:333,100:160]=ball #修改像素值
cv2.namedWindow("messi",0)
cv2.imshow("messi",img)
cv2.waitKey(0)
9.itemset.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
img = cv2.imread('../data/messi5.jpg')
#
px = img[100, 100]
print(px)
blue = img[100, 100, 0]
print(blue)
#
img[100, 100] = [255, 255, 255]
print(img[100, 100])
# 获取像素值及修改的更好方法。
print(img.item(10, 10, 2))
img.itemset((10, 10, 2), 100)
print(img.item(10, 10, 2))
9.MakeBorder.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 为图像扩边,填充
#如果你想在图像周围创建一个边框,就像相框一样
# 经常在卷积运算或 0 填充时被用到。
BLUE = [255, 0, 0]
img1 = cv2.imread('../data/opencv_logo.png')
replicate = cv2.copyMakeBorder(img1, top=10, bottom=10, left=10, right=10, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=BLUE) # value 边界颜色
plt.subplot(231), plt.imshow(img1, 'gray'), plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
plt.show()
9.shape.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
img = cv2.imread('../data/messi5.jpg', 0) # gray
print(img.shape)
img = cv2.imread('../data/messi5.jpg')
# print(img.shape)
rows, cols, ch = img.shape
print('行/高:', rows, '列/宽:', cols, '通道:', ch)
print(img.size)
print(img.dtype)#uint8
#注意 在 debug 时 img.dtype非常重要。因为在 OpenCV- Python 代码中经常出现数据类型的不一致。
9.split_color.py
# -*- coding: utf-8 -*-
import cv2
import numpy as np
#拆分及合并图像通道
img=cv2.imread('../data/messi5.jpg')
#
b,g,r=cv2.split(img)#比较耗时的操作,请使用numpy 索引
img=cv2.merge(b,g,r)
#
b=img[:,:,0]
#使所有像素的红色通道值都为 0,你不必先拆分再赋值。
# 你可以 直接使用 Numpy 索引,这会更快。
img[:,:,2]=0