opencv常用基础操作

import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread('fig3.jpg')

文章目录

  • 0: 黑色 255:白色
    图像读取
  • cv2.imread(src, flags)
    • src:输入图像
    • flags:读入方式,默认为彩色图
      • cv2.IMREAD_COLOR(1):彩色图
      • cv2.IMREAD_GRAYCALE(0):灰度图
      • cv2.IMREAD_UNCHANGED(-1):包含透明通道的彩色图

绘图

线段

  • cv2.line(img, pts, color, thickness, linetype)
    • img: 待绘制的图像
    • pts:起点和zhongdian
    • color:形状的颜色,元组如(255, 0, 0)
    • thinckness:线条的粗细,-1为填充
    • linetype:线条类型,8型或cv2.LINE_AA
img_line = img.copy()
cv2.line(img_line, (0, 0), (500, 250), (255, 0, 255), 4)
cv2.imshow('line', img_line)
cv2.waitKey(0)
cv2.destroyAllWindows()

矩形

  • cv2.rectangle(img, pts, color, thickness, linetype)
    • pts:左上角和右下角坐标
    • others:同cv2.line
img_rectangle = img.copy()
cv2.rectangle(img_rectangle, (250, 50), (500, 250), (255, 0, 0), 3)
cv2.imshow('rectangle', img_rectangle)
cv2.waitKey(0)
cv2.destroyAllWindows()

圆形

  • cv2.circle(img, pts, radius, color, thickness, linetype)
    • pts:圆心
    • radius:半径
    • others:同cv2.line
img_circle = img.copy()
cv2.circle(img_circle, (100, 100), 100, (0, 0, 255), 4)
cv2.imshow('circle', img_circle)
cv2.waitKey(0)
cv2.destroyAllWindows()

椭圆

  • cv2.ellipse(img, central, axis, angle, startAngle, endAngle, color, thickness)
    • central:椭圆中心
    • axis:x/y轴长度
    • angle:椭圆的旋转角度
    • startAngle:椭圆的起始角度
    • endAngle:椭圆的结束角度
img_ellipse = img.copy()
cv2.ellipse(img_ellipse, (100, 100), (100, 50), 90, -90, 90, (255, 0, 255), 4)
cv2.imshow('ellipse', img_ellipse)
cv2.waitKey(0)
cv2.destroyAllWindows()

多边形

  • cv2.polylines(img, pts, isClosed, color, thickness, lineType)
    • pts:表示的是点对,n12维, 形式如下
    • isClosed:布尔型,True表示线段闭合,False表示近保留线段
img_polylines = img.copy()
pts = np.array([[10, 5], [50, 10], [70, 20], [20, 30]])
pts = pts.reshape((-1, 1, 2))
cv2.polylines(img_polylines, [pts], True, (255, 0, 55), 4)
pts2 = np.array([[1,5], [100, 50], [200, 20], [30, 100]])
pts2 = pts2.reshape(-1, 1, 2)
cv2.polylines(img_polylines, [pts2], False, (255, 0, 255), 4)
cv2.imshow('ploylines', img_polylines)
cv2.waitKey(0)
cv2.destroyAllWindows()

添加文字

  • cv2.putText(img, text, pts, font, fontFace, scale, color, thinckness, linetype)
    • text:要添加的文本
    • pts:文字的起始坐标(左下角为起点)
    • font:字体
    • fontFace: 字体类型
    • scale:文字大小(缩放比例)
img_text = img.copy()
cv2.putText(img_text, 'This is a picture.', (0, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 255), 2, cv2.LINE_AA)
cv2.imshow('text', img_text)
cv2.waitKey(0)
cv2.destroyAllWindows()

图像变换

图像平移

  • cv2.warpAffine(src, M, dsize, flags, borderMode, borderValue)
    • src: 输入图像
    • M:变换矩阵,为inputAdarray类型的2*3的变换矩阵。
    • dsize:输出图像的大小
    • flags:插值方法的组合(int类型),默认为cv2.INTER_LINEAR(线性插值)
      此外还有:cv2.INTER_AREA(区域插值)
      cv2.INTER_NEAREST(最近邻插值)
      cv2.INTER_CUBIC(三次样条插值)
      cv2.INTER_LANCZOS4(Lanczos插值)
    • borderMode:边界像素模式(int类型)
    • borderValue:边界填充值;默认为0。
img_path = "fig3.jpg"
img = cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
M = np.float32([[1, 0, 50], [0, 1, 25]]) # x轴移动50, y轴移动100
h, w = img.shape[:2]
res = cv2.warpAffine(img, M, (2 * w, 2 * h))
print('w:', w, 'h:', h)
plt.subplot(1, 2, 1)
plt.imshow(img)
plt.subplot(1, 2, 2)
plt.imshow(res)
plt.show()

图像缩放

  • cv2.resize(src, dsize=None, fx, fy, interpolation)
    • src:原图
    • dsize:输出图像尺寸,与比例因子二选一
    • fx:沿水平轴的比例因子
    • fy:沿垂直轴的比例因子
    • interpolation:插值方法
      • cv2.INTER_NEAREST(最近邻插值) 默认
      • cv2.INTER_LINEAR(线性插值)
      • cv2.INTER_CUBIC(三次样条插值)
      • cv2.INTER_LANCZZOS4(Lanczos插值)
      • cv2.INTER_AREA(区域插值)
img_resize = img.copy()
img_resize = cv2.cvtColor(img_resize, cv2.COLOR_BGR2RGB)
res = cv2.resize(img_resize, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
res2 = cv2.resize(img_resize, (400, 300), cv2.INTER_AREA)
plt.subplot(2, 1, 1)
plt.imshow(res)
plt.subplot(2, 1, 2)
plt.imshow(res2)
plt.show()

图像旋转

设点 P 0 ( x 0 , y 0 ) P_0(x_0, y_0) P0​(x0​,y0​)逆时针旋转 θ \theta θ角后的对应点为 P ( x , y ) P(x, y) P(x,y),那么,旋转后点 P ( x , y ) P(x, y) P(x,y)的坐标是:
x = r c o s ( α + θ ) = r c o s α c o s θ − r s i n α s i n θ = x 0 c o s θ − y 0 s i n θ x = rcos(\alpha+\theta)=rcos\alpha cos\theta-rsin\alpha sin\theta=x_0cos\theta-y_0sin\theta x=rcos(α+θ)=rcosαcosθ−rsinαsinθ=x0​cosθ−y0​sinθ
y = r s i n ( α + θ ) = r s i n α c o s θ + r c o s α s i n θ = x 0 s i n θ + y 0 c o s θ y = rsin(\alpha+\theta)=rsin\alpha cos\theta+rcos\alpha sin\theta=x_0sin\theta+y_0cos\theta y=rsin(α+θ)=rsinαcosθ+rcosαsinθ=x0​sinθ+y0​cosθ

  • cv2.getRotationMatrix2D(center, angle, scale)
    • center:图片的旋转中心
    • angle:旋转角度
    • scale:缩放比例,0.5表示缩小一半,正为逆时针,负为顺时针。
img_rotation = img.copy()
h, w =  img_rotation.shape[:2]
M = cv2.getRotationMatrix2D((w/2, h/2), 30, -1)
dst = cv2.warpAffine(img_rotation, M, (2*w, 2*h), borderValue=(25, 255, 255))
cv2.imshow('rotation', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

仿射变换

仿射变换:平移、旋转、放缩、剪切、反射

  • cv2.getAffineTransform(pos1, pos2)
    • pos1:变换前的位置
    • pos2:变换后的位置
img_affine = img.copy()
h, w = img.shape[:2]
pos1 = np.float32([[50, 50], [200, 50], [50, 200]])
pos2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv2.getAffineTransform(pos1, pos2)
print(M)
dst = cv2.warpAffine(img_affine, M, (w, h))
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

透视变换

本质是将图像投影到一个新的平面。

  • cv2.getPerspectiveTransfoem(pos1, pos2)
    • pos1:透视变换后四个点对应的位置
    • pos2:透视变换后四个点对应的位置
  • cv2.warpPerspective(src, M, (cols, rows))
    • src:原始图像
    • M:透视变换矩阵
    • (cols, rows):变换后的图像大小,row表示行数,col便是列数
src = img.copy()
rows, cols = src.shape[:2]
pos1 = np.float32([[114, 82], [287, 156], [8, 100], [143, 177]])
pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
M = cv2.getPerspectiveTransform(pos1, pos2)
res = cv2.warpPerspective(src, M, (cols, rows))
cv2.imshow('src', src)
cv2.imshow('res', res)
cv2.waitKey(0)

常用图像处理

import cv2
import matplotlib.pyplot as plt
import numpy as np

阈值分割

固定阈值分割

cv2.threahold():固定阈值分割就是像素点大于阈值变成一类值,小于阈值变成一类值。

  • 参数1:要处理的原图,一般是灰度图
  • 参数2:设定阈值
  • 参数3:对于THRESH_BINARYTHRESH_BINARY_INV阈值方法所选用的最大阈值
  • 参数4:阈值的方式,主要有5种
    • cv2.THRESH_BINARY
    • cv2.THRESH_BINARY_INV
    • cv2.THRESH_TRUNC
    • cv2.THRESH_TOZERO
    • cv2.THRESH_TOZERO_INV
methos explain
cv2.THRESH_BINARY d s t ( x , y ) = { m a x v a l i f   s r c ( x , y ) > t h r e s h 0 o t h e r w i s e dst(x, y)=\begin{cases} maxval&if\ src(x, y)>thresh \\ 0&otherwise \end{cases} dst(x,y)={maxval0​if src(x,y)>threshotherwise​
cv2.THRESH_BINARY_INV d s t ( x , y ) = { 0 i f   s r c ( x , y ) > t h r e s h m a x v a l o t h e r w i s e dst(x, y)=\begin{cases}0&if\ src(x, y)>thresh \\ maxval &otherwise \end{cases} dst(x,y)={0maxval​if src(x,y)>threshotherwise​
cv2.THRESH_TRUNC d s t ( x , y ) = { t h r e s h o l d i f   s r c ( x , y ) > t h r e s h s r c ( x , y ) o t h e r w i s e dst(x, y)=\begin{cases} threshold &if\ src(x, y)>thresh \\ src(x, y) & otherwise \end{cases} dst(x,y)={thresholdsrc(x,y)​if src(x,y)>threshotherwise​
cv2.THRESH_TOZERO d s t ( x , y ) = { s r c ( x , y ) i f   s r c ( x , y ) > t h r e s h 0 o t h e r w i s e dst(x, y)=\begin{cases}src(x, y) &if\ src(x, y)>thresh \\ 0 &otherwise \end{cases} dst(x,y)={src(x,y)0​if src(x,y)>threshotherwise​
cv2.THRESH_TOZERO_INV d s t ( x , y ) = { 0 i f   s r c ( x , y ) > t h r e s h s r c ( x , y ) o t h e r w i s e dst(x, y)=\begin{cases}0 &if\ src(x, y)>thresh \\ src(x, y) &otherwise \end{cases} dst(x,y)={0src(x,y)​if src(x,y)>threshotherwise​
img = cv2.imread('img/fig2.jpg', 0)

ret, th = cv2.threshold(img, 80, 155, cv2.THRESH_BINARY)
cv2.imshow('thresh', th)
cv2.waitKey(0)

来看五种不同的阈值分割方式:

img = cv2.imread('img/fig2.jpg', 0)

ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
ret, th2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
ret, th3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
ret, th4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
ret, th5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)

titles = ['orginal', 'binary', 'binary_inv', 'trunc', 'tozero', 'to_zero_inv']
images = [img, th1, th2, th3, th4, th5]

for i in range(6):
    plt.subplot(3, 2, i+1)
    plt.imshow(images[i])
    plt.title(titles[i], fontsize=8)
    plt.axis('off')
plt.show()

自适应阈值

固定阈值是在整个图片上应用一个阈值进行分割,因此并不适用于明暗分布不均的图片。
cv2.adaptiveThreshold()自适应阈值会每次取图片的一小部分计算阈值,这样图片不同区域的阈值就不尽相同。

  • 参数1:要处理的原图
  • 参数2:最大阈值,一般为255
  • 参数3:小区域阈值的计算方式
    • ADAPTIVE_THRESH_MEAN_C:小区域内取均值
    • ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是个高斯核
  • 参数4:阈值方法,只能使用THRESH_BINARY, THRESH_BINAY_INV
  • 参数5:小区域的面积
  • 参数6:最终阈值等于小区域计算出的阈值再减去此值
img = cv2.imread('img/fig2.jpg', 0)

ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 4)
th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 17, 6)

titles = ['orginal', 'global(v=127)','adaptive mean', 'adaptive gaussian']
images = [img, th1, th2, th3]

for i in range(4):
    plt.subplot(2, 2, i+1)
    plt.imshow(images[i])
    plt.axis('off')
    plt.title(titles[i])
plt.show()

滤波

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('fig3.jpg')

方框滤波

  • cv2.boxFilter(src, depth, ksize, normalize)
    • src:输入tuxiang
    • depth:目标图像深度
    • ksize:核大小
    • normalize:normalize属性
src = img.copy()
dst = cv2.boxFilter(src, -1, (9, 9), normalize=1)
dst2 = cv2.boxFilter(src, -1, (9, 9), normalize=0)
cv2.imshow('dst', dst)
cv2.imshow('dst2', dst)
cv2.imshow('src', src)
cv2.waitKey(0)

均值滤波

  • cv2.blur(src, kszie)
    • src:输入原图
    • ksize:kernel大小,一般为奇数
src = img.copy()
dst = cv2.blur(src, (9, 9))
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey(0)

高斯滤波

  • cv2.GaussianBlur(src, ksize, std)
    • src: 输入原图
    • ksize:高斯核大小
    • std:标准差 σ \sigma σ, σ \sigma σ越大滤波结果越平滑
src = img.copy()
blur = cv2.GaussianBlur(src, (5, 5), 3)
cv2.imshow('src', src)
cv2.imshow('blur', blur)
cv2.waitKey()

中值滤波

  • cv2.medianBlur(img, ksize)
    • img: 输入原图
    • ksize:核大小
src = img.copy()
blur = cv2.medianBlur(src, 5)
cv2.imshow('src', src)
cv2.imshow('blur', blur)
cv2.waitKey()

双边滤波

双边滤波是一种非线性的滤波方法,同时考虑空间信息和灰度相似性,达到报边去噪的目的。

  • cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)
    • src:输入原图
    • d:像素的邻域直径
    • sigmaColor:灰度值相似性高斯函数标准差
    • sigmaSpace:空间高斯函数标准差
src = img.copy()
blur = cv2.bilateralFilter(src, -1, 15, 10)
cv2.imshow('src', src)
cv2.imshow('blur', blur)
cv2.waitKey()

图像增强

直方图均衡化

统计直方图中每个灰度级出现的次数,计算累计归一化直方图,重新计算像素点的像素值。

  • cv2.equalizeHist(img)
    彩色图像的直方图均衡化需要对对每个通道单独进行均衡化,然后再合并到一起。
src = cv2.imread('img/fig2.jpg', 0)
dst = cv2.equalizeHist(src)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey(0)
src = cv2.imread('img/fig2.jpg')
(r, g, b) = cv2.split(src)
rh = cv2.equalizeHist(r)
bh = cv2.equalizeHist(b)
gh = cv2.equalizeHist(g)
dst = cv2.merge((rh, gh, bh))
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey(0)

Gamma变换

Gamma变换是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入图像灰度值呈指数关系。
V o u t = A V i n γ V_{out} = AV_{in}^\gamma Vout​=AVinγ​
目的:提升暗部细节。即将漂白(相机曝光)或过暗(曝光不足)的图片进行矫正。

def adjust_gamma(src, gamma=1.0):
  invGamma = 1.0/gamma
  table = []
  for i in range(256):
    table.append(((i / 255) ** invGamma) * 255)
  table = np.array(table).astype('uint8')
  return cv2.LUT(src, table)
src = cv2.imread('img/fig2.jpg')
dst = adjust_gamma(src, 1.5)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()

腐蚀

A − B = { x ∣ B X ⊆ A } A-B=\{x|B_X\subseteq A\} A−B={x∣BX​⊆A}
g该公式表示图像A用卷积模板B来进行腐蚀处理,通过模板B与图像A进行卷积计算,得出B覆盖区域的像素点最小值,并用这个最小值来替代参考点的像素值。

  • cv2.erode(src, element, anchor, iterations)
    • src: 原图像
    • element:腐蚀操作的内核,默认为3*3的矩形
    • anchor:内核中心点,默认为(-1, -1)
    • iterations:腐蚀次数,默认1
src = cv2.imread('img/fig2.jpg')
kernel = np.ones((3, 3),np.uint8)
dst = cv2.erode(src, kernel, iterations=2)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey(0)

膨胀

定义kernel

  • cv2.getStructuringElement(shape, ksize): 返回指定形状和尺寸的结构元素
  • shape: 表示内核的形状
    • 矩形:cv2.MORPH_RECT
    • 十字形:cv2.MORPH_CROSS
    • 椭圆形: cv2.MORPH_ELLIPSE
  • ksize:结构元素的大小
    膨胀操作
  • cv2.dilate(src, element, anchor, iterations)
    • src: 输入图像
    • element:结构元素
    • anchor:内核中心点,moren(-1, -1)
    • iterations:迭代次数

开闭运算

开运算

先腐蚀, 再膨胀。
开运算能除去孤立的小点,毛刺和小桥,而总的位置和形状不变。
cv2.MORPH_OPEN

闭运算

先膨胀,后腐蚀。
闭运算能够填平小孔,弥合小裂缝,而总的位置和形状不变。
cv2.MORPH_CLOSE

顶帽
原图像与开运算图的差值,突出原图像中比周围亮的区域。
cv2.MORPH_TOPHAT

黑帽
闭操作图像与原图像的差值,突出原图像中比周围暗的区域。
cv2.MORPH_BLACKHAT

  • cv2.morphologyEx()

形态学梯度

基础梯度:基础梯度是用膨胀后的图像减去腐蚀后的图像得到的插值图像。
内部梯度:用原图像减去腐蚀之后的图像得到的插值图像,称为图像的内部梯度。
外部梯度:膨胀之后的图像减去原来的图像得到的插值图像。

cv2.MORPH_GRADIENT(基础梯度)

视频操作

import cv2
import numpy as np
import matplotlib.pyplot as ply

打开摄像头

cv2.VideoCapture(0): 创建VideoCapture,对象,0是摄像头编号

windows系统下,采用dshow流媒体机制时需要使用cv2.CAP_DSHOW作为cv2.VideoCapture(0, cv2.CAP_DSHOW)的参数

capture = cv2.VideoCapture(0)
cv2.namedWindow("thresh", cv2.WINDOW_AUTOSIZE)
while(True):
    ret, frame = capture.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 二值化
    # _, thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
    # 获取捕获的分辨率
    # propId可以直接写数字,也可以用OpenCV的符号表示
    width, height = capture.get(3), capture.get(4)
    # print(width, height)

    # 以原分辨率的一倍来捕获
    capture.set(cv2.CAP_PROP_FRAME_WIDTH, width * 2)
    capture.set(cv2.CAP_PROP_FRAME_HEIGHT, height * 2)
    cv2.imshow('frame', frame)
    # 灰度图
    # cv2.imshow('gary', gray)
    # cv2.imshow('thresh', thresh)
    if cv2.waitKey(1) == 27:
        break
  • capture.read()函数返回的第一个参数是一个布尔值,表示当前这一帧是否获取正确。
  • capture.get()可以获取摄像头的一些属性
  • capture.set()可以修改这些属性值
参数 含义
0:CV_CAP_PROP_POS_MSEC 视频文件的当前位置(毫秒)
1:CV_CAP_PROP_POS_FRAMES 基于0的索引的下一个要解码/捕获的帧。
CV_CAP_PROP_POS_AVI_RATIO 视频文件的相对位置:0-胶片开始,1-胶片结束。
CV_CAP_PROP_FRAME_WIDTH 视频流中帧的宽度。
CV_CAP_PROP_FRAME_HEIGHT 视频流中帧的高度。
CV_CAP_PROP_FPS 帧速率。
CV_CAP_PROP_FOURCC 编解码器的4字符代码。
CV_CAP_PROP_FRAME_COUNT 视频文件中的帧数。
CV_CAP_PROP_FORMAT 返回的Mat对象的格式。
CV_CAP_PROP_MODE 后端特定值,指示当前捕获模式。
CV_CAP_PROP_BRIGHTNESS 图像亮度(仅适用于相机)
CV_CAP_PROP_CONTRAST 图像对比度(仅适用于相机)
CV_CAP_PROP_SATURATION 图像的饱和度(仅适用于相机)
CV_CAP_PROP_HUE 图像的色调(仅适用于相机)
CV_CAP_PROP_GAIN 图像增益(仅适用于相机)
CV_CAP_PROP_EXPOSURE 曝光(仅适用于相机)
CV_CAP_PROP_CONVERT_RGB 指示是否应将图像转换为RGB的布尔标志。
CV_CAP_PROP_WHITE_BALANCE 当前不支持
CV_CAP_PROP_RECTIFICATION 立体相机的校正标志(注:仅DC1394 v 2.x后端当前支持)

播放本地视频

把摄像头换成文件路径即可,cv2.waitKey()的参数表示暂停的时间,一般为25或30.

capture = cv2.VideoCapture('/home/jokesnow/Videos/minzu.mp4')
while(capture.isOpened()):
    ret, frame = capture.read()
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) == 27:
        break

录制视频

保存图片使用cv2.imwrite(),保存视频我们需要创建一个VideoWriter的对象,然后传给它四个参数:

  • 输出的文件名
  • 编码方式FourCC码
    • FourCC是用来指定视频编码方式的四字节码。如MJPG编码可以这样写:cv2.VideoWriter_fourcc(*'MJPG')cv2.VideoWriter_fourcc('M', 'j', 'p', 'G')
    • 帧率FPS
    • 要保存的分辨率大小
capture = cv2.VideoCapture(0)

# 定义编码方式并创建VideoWriter对象
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
outfile = cv2.VideoWriter('/home/jokesnow/Videos/output.avi', fourcc, 25., (640, 480))

while(capture.isOpened()):
    ret, frame = capture.read()
    if ret:
        outfile.write(frame)
        cv2.imshow('frame', frame)
        if cv2.waitKey(1) == 27:
            break
    else:
        break

特定颜色物体追踪

步骤:

  1. 捕获视频中的一帧
  2. 从BGR转换到HSV
  3. 提取蓝色范围的物体
  4. 只显示蓝色物体
import numpy as np

capture = cv2.VideoCapture(0)
# 蓝色的范围
lower_blue = np.array([100, 100, 100])
upper_blue = np.array([130, 255, 255])

while(True):
    # 捕获一帧
    ret, frame = capture.read()
    # 从BGR转换到HSV
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    # inRange():介于lower/upper之间的为白色,其余为黑色
    mask = cv2.inRange(hsv, lower_blue, upper_blue)
    # 只保留蓝色
    res = cv2.bitwise_and(frame, frame, mask=mask)

    cv2.imshow('frame', frame)
    cv2.imshow('mask', mask)
    cv2.imshow('res', res)

    if cv2.waitKey(1) == 27:
        break

颜色HSV范围的获取:

blue = np.uint8([[[255, 0, 0]]])
red = np.uint8([[[0, 0, 255]]])
green = np.uint8([[[0, 255, 0]]])
hsv_blue = cv2.cvtColor(blue, cv2.COLOR_BGR2HSV)
hsv_green = cv2.cvtColor(green, cv2.COLOR_BGR2HSV)
hsv_red = cv2.cvtColor(red, cv2.COLOR_BGR2HSV)
print('b:', hsv_blue, 'g:', hsv_green, 'r:', hsv_red)

提取红绿蓝三种颜色

import numpy as np

capture = cv2.VideoCapture(0)
# 蓝色的范围
lower_blue = np.array([90, 100, 100])
upper_blue = np.array([140, 255, 255])
lower_green = np.array([40, 100, 100])
upper_green = np.array([80, 255, 255])
lower_red = np.array([0, 100, 100])
upper_red = np.array([30, 255, 255])

while(True):
    ret, frame = capture.read()

    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    mask_blue= cv2.inRange(hsv, lower_blue, upper_blue)
    mask_green= cv2.inRange(hsv, lower_green, upper_green)
    mask_red= cv2.inRange(hsv, lower_red, upper_red)
    res1 = cv2.bitwise_and(frame, frame, mask=mask_blue)
    res2 = cv2.bitwise_and(frame, frame, mask=mask_green)
    res3 = cv2.bitwise_and(frame, frame, mask=mask_red)
    res = res1 + res2 + res3
    
    cv2.imshow('frame', frame)
    cv2.imshow('mask_blue', mask_blue)
    cv2.imshow('mask_green', mask_green)
    cv2.imshow('mask_red', mask_red)
    cv2.imshow('res', res)

    if cv2.waitKey(1) == 27:
        break
上一篇:TMS320C6455入门实践(七)——生成启动镜像


下一篇:【C】模拟实现mem系列和str系列函数