首页 > 其他分享 >opencv笔记(一)

opencv笔记(一)

时间:2022-12-05 19:22:42浏览次数:38  
标签:des img imshow cv2 笔记 opencv np import

opencv笔记(一)

目录

环境搭建

  • python3环境
  • pip install numpy matplotlib opencv-python

基础用法

常用对象

  • 窗口
  • 摄像设备
  • 视频写入
import cv2

# 创建fourcc对象
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 创建VideoWriter对象,参数为1.文件路径、fourcc、帧率、分辨率
vw = cv2.VideoWriter('d.mp4', fourcc, 24, (640, 480))
# 创建窗口对象
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
# 创建摄像设备对象,参数为设备序列号
cap = cv2.VideoCapture(0)

while cap.isOpened():
    ok, frame = cap.read()
    if ok:
        # 屏幕显示
        cv2.imshow('video', frame)
        # 保存
        vw.write(frame)
        key = cv2.waitKey(6)
        if key & 0xFF == ord('q'):
            break
    else:
        break

# 释放资源
cap.release()
vw.release()
cv2.destroyAllWindows()
  • 鼠标回调函数
import cv2
import numpy as np


# 定义回调函数体,参数:1.事件、2.宽、3.高、4.鼠标键或者组合键、5.设置鼠标回调函数时传入的userdata
def mouse_callback(event, x, y, flag, userdata):
    print(event, x, y, flag, userdata)


# 创建窗口对象
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('video', 1280, 720)
# 设置鼠标回调函数,参数:1.窗口名、2.回调函数、3.userdata值
cv2.setMouseCallback('video', mouse_callback, 'userdata')

img = np.zeros((720, 1280, 3), np.uint8)

while 1:
    # 屏幕显示
    cv2.imshow('video', img)
    key = cv2.waitKey(6)
    if key & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()
  • TrackBar
import cv2
import numpy as np


def callback(userdata):
    print(userdata)


cv2.namedWindow('trackbar', cv2.WINDOW_NORMAL)
cv2.resizeWindow('trackbar', 640, 320)

# 创建trackbar
cv2.createTrackbar('R', 'trackbar', 0, 255, callback)
cv2.createTrackbar('G', 'trackbar', 0, 255, callback)
cv2.createTrackbar('B', 'trackbar', 0, 255, callback)

img = np.zeros((320, 640, 3), np.uint8)

while 1:
    # 屏幕显示
    r = cv2.getTrackbarPos('R', 'trackbar')
    g = cv2.getTrackbarPos('G', 'trackbar')
    b = cv2.getTrackbarPos('B', 'trackbar')
    img[:] = [b, g, r]
    cv2.imshow('trackbar', img)
    key = cv2.waitKey(6)
    if key & 0xFF == ord('q') or cv2.getWindowProperty('trackbar', cv2.WND_PROP_VISIBLE) < 1.0:
        break

cv2.destroyAllWindows()

色彩空间

  • BGR
  • RGB
  • HSV:色相+饱和度+明度
  • HSL:色相+饱和度+亮度
  • YUV
import cv2


def callback(userdata):
    print(userdata)


cv2.namedWindow('color', cv2.WINDOW_NORMAL)

img = cv2.imread('1.png')

color_spaces = [cv2.COLOR_BGR2BGRA, cv2.COLOR_BGR2GRAY, cv2.COLOR_BGR2HSV_FULL, cv2.COLOR_BGR2RGBA, cv2.COLOR_BGR2YUV]

cv2.createTrackbar('trans', 'color', 0, len(color_spaces)-1, callback)

while 1:
    v = cv2.getTrackbarPos('trans', 'color')
    # 色彩空间转换
    new_img = cv2.cvtColor(img, color_spaces[v])
    cv2.imshow('color', new_img)
    key = cv2.waitKey(6)
    if key & 0xFF == ord('q') or cv2.getWindowProperty('color', cv2.WND_PROP_VISIBLE) < 1.0:
        break

cv2.destroyAllWindows()

Numpy基础

创建矩阵

  • 通过array:np.array[[1, 2, 3], [4, 5, 6]]
  • 通过zeros:np.zeros((320, 640, 3), np.uint8)
  • 通过ones:np.ones((320, 640, 3), np.uint8)
  • 通过full:np.full((8, 8, 3), 255, np.uint8)
  • 通过identity:np.identity(4)
  • 通过eye:np.eye(3, 5, k=2)

矩阵取值与赋值

  • img[y, x]:[1, 2, 3]
  • img[y, x, channel]:1

ROI

  • img[y1:y2, x1:x2]
  • img[:, :]
import cv2
import numpy as np

cv2.namedWindow('color', cv2.WINDOW_NORMAL)

img = np.full((320, 640, 3), 0, np.uint8)
img[100:200, 100:200] = [0, 0, 255]
img[:, 300] = [255, 0, 0]

cv2.imshow('color', img)
key = cv2.waitKey(0)
if key & 0xFF == ord('q') or cv2.getWindowProperty('color', cv2.WND_PROP_VISIBLE) < 1.0:
    cv2.destroyAllWindows()

Mat

结构

  • header:dims维度、rows行数、cols列数、depth像素位深、channels通道数、size矩阵大小、type
  • data:矩阵详细数据

拷贝

当显式调用copy()生成新矩阵时会拷贝header和data,否则只拷贝header。

import cv2
import numpy as np

cv2.namedWindow('color', cv2.WINDOW_NORMAL)

img = np.full((320, 640, 3), 0, np.uint8)

img2 = img[:]
img2[:] = [0, 0, 255]

img3 = img.copy()
img3[100:200, 100:200] = [255, 0, 0]

cv2.imshow('color', img)
cv2.imshow('color2', img2)
cv2.imshow('color3', img3)
key = cv2.waitKey(0)
if key & 0xFF == ord('q') or cv2.getWindowProperty('color', cv2.WND_PROP_VISIBLE) < 1.0:
    cv2.destroyAllWindows()

属性访问

  • img.shape:高、宽、通道数
  • img.size:高x宽x通道数
  • img.dtype:位深,例如uint8

通道的分离与合并

  • split(mat)
  • merge((chan1, chan2))
import cv2
import numpy as np

img = np.zeros((320, 640, 3), np.uint8)

b, g, r = cv2.split(img)  # split将同时拷贝header与data
b[100:200, 100:200] = 255
g[100:200, 100:200] = 255
r[0:100, 0:100] = 255
img2 = cv2.merge((b, g, r))  # merge将同时拷贝header与data
img2[200:300, 200:300] = [0, 0, 255]

cv2.imshow('color', img)
cv2.imshow('color0', img2)
cv2.imshow('color1', b)
cv2.imshow('color2', g)
cv2.imshow('color3', r)

key = cv2.waitKey(0)
if key & 0xFF == ord('q'):
    cv2.destroyAllWindows()

图形绘制

  • 线:line
  • 矩形:rectangle
  • 圆:circle
  • 椭圆:ellipse
  • 多边形:
  • 字体:
import cv2
import numpy as np

# 此处坐标参数为y, x顺序
img = np.zeros((320, 640, 3), np.uint8)

# 此处坐标相关参数全部是(x, y)顺序,参数:图像、起始点、终止点、颜色、线宽、线形
cv2.line(img, (10, 20), (100, 200), (255, 0, 0), 5)

#矩形
cv2.rectangle(img, (80, 80), (200, 200), (0, 255, 0))

# 圆
cv2.circle(img, (140, 140), 60, (0, 0, 255))

# 椭圆 参数:图像、圆心、x和y半径、顺时针旋转角度、绘制起始角度、绘制终止角度、颜色、厚
cv2.ellipse(img, (140, 140), (60, 30), 90, 0, 360, (0, 0, 255), -1)

# 多边形 参数:图像、点、是否闭合、颜色
points = np.array([(300, 5), (132, 109), (480, 109)], np.int32)
cv2.polylines(img, [points], True, (0, 0, 255))

# 填充的多边形 参数:图像、点、颜色
points_fill = np.array([(300, 10), (150, 100), (450, 100)], np.int32)
cv2.fillPoly(img, [points_fill], (255, 0, 0))

# 文本 参数:图像、文本内容、起始点、字体、字号、颜色
cv2.putText(img, 'test', (200, 300), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255))

cv2.imshow('line', img)

key = cv2.waitKey(0)
if key & 0xFF == ord('q'):
    cv2.destroyAllWindows()

基本图像运算与处理

加法运算

import cv2
import numpy as np

# 加法运算
# 必须确保两张图像大小通道一致
im1 = cv2.imread('x.png')
# im2 = cv2.imread('y.png')
im2 = np.ones((1080, 1920, 3), np.uint8) * 100

cv2.imshow('add', cv2.add(im1, im2))
cv2.waitKey(0)

减法运算

import cv2
import numpy as np

# 减法运算
# 必须确保两张图像大小通道一致
# 注意受np.uint8类型约束,加法运算逆运算后可能得到与原图有偏差的结果
im1 = cv2.imread('x.png')
im2 = np.ones(im1.shape, np.uint8) * 10

cv2.imshow('ori', im1)
cv2.imshow('subtract', cv2.subtract(cv2.add(im1, im2), im2))
cv2.waitKey(0)

乘除运算

import cv2
import numpy as np

# 减法运算
# 必须确保两张图像大小通道一致
# 注意受np.uint8类型约束,加法运算逆运算后可能得到与原图有偏差的结果
im1 = cv2.imread('x.png')
im2 = np.ones(im1.shape, np.uint8) * 10

cv2.imshow('ori', im1)
cv2.imshow('multiply', cv2.multiply(im1, im2))
cv2.imshow('divide', cv2.divide(im1, im2))
cv2.waitKey(0)

图像溶合

即带权重的图像叠加

import cv2


im1 = cv2.imread('x.png')
im2 = cv2.imread('y.png')

# 参数:图像一、图像一权重、图像二、图像二权重、静态权重
cv2.imshow('addWeighted', cv2.addWeighted(im1, 0.6, im2, 0.4, 0))
cv2.waitKey(0)

图像位运算

  • 异或

import cv2
import numpy as np

im1 = np.zeros((200, 200), np.uint8)
im2 = np.zeros((200, 200), np.uint8)

im1[20:120, 20:120] = 255
im2[80:180, 80:180] = 255

cv2.imshow('not', cv2.bitwise_not(im1))
cv2.imshow('and', cv2.bitwise_and(im1, im2))
cv2.imshow('or', cv2.bitwise_or(im1, im2))
cv2.imshow('xor', cv2.bitwise_xor(im1, im2))
cv2.waitKey(0)

图像的变换

图像缩放

import cv2

# 图像缩放
"""
参数:源、缩放后大小、X轴缩放因子、Y轴缩放因子、插值算法,同时指定大小和缩放因子优先取大小
插值算法:INTER_NEAREST(临近插值,速度快,效果差)、INTER_LINEAR(双线性插值,参考周围4点)
INTER_CUBIC(三次插值,参考16点)、INTER_AREA(效果最好)
"""
img = cv2.imread('1.png')
res = cv2.resize(img, (1920, 1080))
res2 = cv2.resize(img, None, fx=0.6, fy=0.6)

cv2.imshow('resize1', res)
cv2.imshow('resize2', res2)
cv2.waitKeyEx(0)

图像翻转

import cv2

# 图像翻转
# 参数:图像、翻转标志(0代表上下翻转, >0代表左右翻转, <0代表上下+左右)
img = cv2.imread('1.png')

cv2.imshow('flip', cv2.flip(img, -1))
cv2.waitKeyEx(0)

图像旋转

import cv2

# 图像旋转
# 参数:图像、旋转标志(ROTATE_90_CLOCKWISE, ROTATE180, ROTATE_90_COUNTERCLOCKWISE)
img = cv2.imread('1.png')

cv2.imshow('rotate', cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE))
cv2.waitKeyEx(0)

仿射变换

即图像旋转、缩放、平移的总称

import cv2
import numpy as np

img = cv2.imread('1.png')
# 仿射变换
# 参数:图像、变换矩阵、输出大小、flag插值算法、mode边界外推法标志、value填充边界的值
# X轴平移100
M = np.float32([[1, 0, 100], [0, 1, 0]])

h, w, _ = img.shape
cv2.imshow('warpAffine', cv2.warpAffine(img, M, (w, h)))

# 通过API获取变换矩阵
# 参数:中心点、角度(逆时针)、缩放比例
# 变换不改变图像大小,如果要修改图像大小需要修改dsize
M = cv2.getRotationMatrix2D((100, 100), 30, 1.0)
cv2.imshow('warpAffine2', cv2.warpAffine(img, M, (w, h)))

# 通过API获取变换矩阵-三点定位
# 参数:原三点、目的三点
ori = np.float32([[100, 200], [300, 200], [100, 400]])
new = np.float32([[150, 300], [200, 400], [50, 350]])
M = cv2.getAffineTransform(ori, new)
cv2.imshow('warpAffine3', cv2.warpAffine(img, M, (w, h)))

cv2.waitKeyEx(0)

透视变换

import cv2
import numpy as np

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

# 获取变换矩阵
# 参数:原四点、目标四点
src = np.float32([[100, 1100], [2100, 1100], [0, 4000], [2500, 3900]])
des = np.float32([[0, 0], [2300, 0], [0, 3000], [2300, 3000]])
M = cv2.getPerspectiveTransform(src, des)

# 透视变换
# 参数:图像、变换矩阵、输出大小...
warp_perspective = cv2.warpPerspective(img, M, (2300, 3000))

cv2.imshow('warpPerspective', warp_perspective)

cv2.waitKeyEx(0)

图像滤波

一幅图像通过滤波器得到另一幅图像。

卷积

滤波器又称卷积核,滤波的过程称为卷积。

  • 卷积核的大小:

    一般为奇数(原因包括增加padding和确保锚点居中),例如3x3、5x5等,在深度学习中,卷积核越大,感受野越大,信息越多,提取的特征越好,同时计算量也越大

  • 锚点:卷积核中心点

  • 边界扩充:

    当卷积核大于1且不进行边界扩充,输出尺寸将相应缩小

    当卷积核一标准方式进行边界扩充,则输出数据的空间尺寸将与输入相等

    N = (W - F + 2P) / S + 1

    N即输出图像大小,W源大小,F卷积核大小,P扩充尺寸,S步长大小

  • 步长

低通滤波:低于某个阈值的值可以通过,可以去除噪音或者平滑图像

高通滤波:高于某个阈值的值可以通过,可以帮助查找图像边缘

常用滤波器

低通滤波
滤波器名 作用或优点 缺点 备注
*方盒滤波(boxFilter) / / normalize=True时为均值滤波,使用较少
均值滤波(blur) 平滑图像,减少锐化 失去纹理 /
高斯滤波(GaussianBlur) 涂抹噪点 边缘模糊 越靠近中心,权重越高,锚点权重约0.148
中值滤波(medianBlur) 消除胡椒噪音 对其他噪音效果不佳,边缘模糊 取卷积数组的中值作为卷积结果
双边滤波(bilateralFilter) 保留边缘同时对边缘内区域进行平滑处理 胡椒噪音效果不佳
高通滤波
算子 作用或优点 缺点 备注
索贝尔(Sobel) 抗噪 同时求一个以上方向边缘时效果极差 卷积核大小为-1时即沙尔
*沙尔(Scharr) 细小边缘检测 只能同时求一个方向上的边缘 使用较少
拉普拉斯(Laplacian) 同时求多方向边缘 噪音敏感 使用前需要先做降噪处理
边缘检测-Canny

内部实现步骤

  1. 使用5x5高斯滤波消除噪声
  2. 从四个方向计算图像梯度:0°/45°/90°/135°
  3. 取局部极大值
  4. 阈值计算:高于最大值即是边缘,低于最小值即不是边缘,中间值如与以确定边缘有连续关系则是边缘,否则不是边缘
import cv2
import numpy as np

img = cv2.imread('8.png')

# 图像卷积
# 参数:图像、位深,卷积核,锚点,指定偏差,边界类型
# kernel = np.ones((5, 5), np.float32) / 25
# des = cv2.filter2D(img, -1, kernel)

# 均值滤波,参数:源、卷积核大小...
# blur_des = cv2.blur(img, (5, 5))

# 高斯滤波,参数:源、卷积核(大小)、sigma(值越大越模糊,未指定时参考卷积核大小)
# gauss_des = cv2.GaussianBlur(img, (5, 5), sigmaX=3)

# 中值滤波,参数:源、卷积核大小
# median_des = cv2.medianBlur(img, 5)

# 双边滤波,参数:源、filter大小、颜色sigma、sigma空间
# bil_des = cv2.bilateralFilter(img, 6, 20, 50)

# 索贝尔算子,参数:源、输出位深、对X求导、对Y求导、核大小...
# sobel_des = cv2.add(cv2.Sobel(img, cv2.CV_64F, 1, 0, 5), cv2.Sobel(img, cv2.CV_64F, 0, 1, 5))

# 拉普拉斯算子,参数:源、输出位深、核大小
# lap_des = cv2.Laplacian(img, cv2.CV_64F, ksize=5)

# Canny,参数:源、最小值、最大值
canny_des = cv2.Canny(img, 100, 200)

cv2.imshow('ori', img)
# cv2.imshow('des', des)
# cv2.imshow('blur_des', blur_des)
# cv2.imshow('gauss_des', gauss_des)
# cv2.imshow('median_des', median_des)
# cv2.imshow('bil_des', bil_des)
# cv2.imshow('sobel_des', sobel_des)
# cv2.imshow('lap_des', lap_des)
cv2.imshow('canny_des', canny_des)

cv2.waitKeyEx(0)

形态学

图像二值化

全局二值化

将图像的每个像素变成两种值

import cv2
import numpy as np

ori_img = cv2.imread('8.png')
img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)

# 全局二值化,参数:源、阈值、用于替换超过最大值的值、类型
# 类型包含THRESH_BINARY、THRESH_BINARY_INV、THRESH_TRUNC、THRESH_TOZERO、THRESH_TOZERO_INV
_, des = cv2.threshold(img, 140, 255, cv2.THRESH_BINARY)

# 全局二值化(自适应阈值),参数:源、用于替换超过最大值的值、自适应方法、类型、自适应区域、从计算出的平均值或者加权平均值中减去的常量
# 自适应方法:ADAPTIVE_THRESH_MEAN_C(计算邻近区域的平均值)、ADAPTIVE_THRESH_GAUSSIAN_C(高斯窗口加权平均值)
# 类型包含THRESH_BINARY、THRESH_BINARY_INV
auto_des = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 15, 0)

cv2.imshow('ori', ori_img)
cv2.imshow('des', des)
cv2.imshow('auto_des', auto_des)

cv2.waitKeyEx(0)

腐蚀

import cv2
import numpy as np

ori_img = cv2.imread('8.png')
img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
_, des = cv2.threshold(img, 140, 255, cv2.THRESH_BINARY)

# 手动构建卷积核
# kernel = np.ones((3, 3), np.uint8)

# 获取卷积核,参数:卷积核类型、卷积核大小
# 卷积核类型:MORPH_RECT(全1)、MORPH_ELLIPSE(椭圆核,四角为0)、MORPH_CROSS(十字核,横竖为1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))


# 腐蚀,参数:源、卷积核、腐蚀次数
erode_des = cv2.erode(des, kernel)

cv2.imshow('ori', ori_img)
cv2.imshow('erode_des', erode_des)

cv2.waitKeyEx(0)

膨胀

import cv2
import numpy as np

ori_img = cv2.imread('8.png')
img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
_, des = cv2.threshold(img, 140, 255, cv2.THRESH_BINARY)

# 手动构建卷积核
# kernel = np.ones((3, 3), np.uint8)

# 获取卷积核,参数:卷积核类型、卷积核大小
# 卷积核类型:MORPH_RECT(全1)、MORPH_ELLIPSE(椭圆核,四角为0)、MORPH_CROSS(十字核,横竖为1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))


# 腐蚀,参数:源、卷积核、腐蚀次数
erode_des = cv2.erode(des, kernel)

# 膨胀,参数:源、卷积核、腐蚀次数
dilate_des = cv2.dilate(des, kernel)

cv2.imshow('ori', ori_img)
cv2.imshow('erode_des', erode_des)
cv2.imshow('dilate_des', dilate_des)

cv2.waitKeyEx(0)

开运算

先做腐蚀后做膨胀

用于消除背景中的小图形,保留大图形,可以理解为消除主要目标外的背景中的噪点

闭运算

先做膨胀后做腐蚀

用于消除大图形中的小图形,可以理解为消除主要目标中的噪点

梯度运算

梯度=原图-腐蚀后的图,用于得到目标图形的边缘,一定条件下,卷积核越小,得到的边缘越清晰而细小,卷积核越大,得到的边缘越模糊

顶帽运算

顶帽=原图-开运算,用于得到主要目标图形外的小图形,可以理解为获取背景中的噪点

黑帽运算

黑帽=原图-闭运算,用于得到主要图形中的小图形,可以理解为获取目标图形中的噪点

import cv2

ori_img = cv2.imread('8.png')
img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(img, 140, 255, cv2.THRESH_BINARY)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

# 开运算,参数:源、宏类型(MORPH_OPEN)、卷积核
morph_open = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

# 闭运算,参数:源、宏类型(MORPH_CLOSE)、卷积核
morph_close = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

# 梯度运算,参数:源、宏类型(MORPH_GRADIENT)、卷积核
morph_gr = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

# 顶帽运算,参数:源、宏类型(MORPH_TOPHAT)、卷积核
morph_top = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

# 黑帽运算,参数:源、宏类型(MORPH_BLACKHAT)、卷积核
morph_black = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

cv2.imshow('ori', ori_img)
cv2.imshow('morph_open', morph_open)
cv2.imshow('morph_close', morph_close)
cv2.imshow('morph_gr', morph_gr)
cv2.imshow('morph_top', morph_top)
cv2.imshow('morph_black', morph_black)


cv2.waitKeyEx(0)
运算名 步骤(方法) 作用
开运算 先做腐蚀后做膨胀,MORPH_OPEN 消除背景中的噪点
闭运算 先做膨胀后做腐蚀,MORPH_CLOSE 消除主要目标中的噪点
梯度运算 原图-腐蚀后的图,MORPH_GRADIENT 得到目标图形的边缘
顶帽运算 原图-开运算,MORPH_TOPHAT 获取背景中的噪点
黑帽运算 原图-闭运算,MORPH_BLACKHAT 获取目标图形中的噪点

轮廓查找

图像轮廓即具有相同颜色或强度的连续点的曲线。

图像轮廓的作用

  1. 图形分析
  2. 物体的识别与检测

查找轮廓注意

  • 需要先对图像进行二值化或Canny操作
  • 画轮廓会修改输入图像(需要拷贝)
  • 通常会将背景设置为黑色,目标设置为白色
import cv2

ori_img = cv2.imread('9.png')
img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(img, 140, 255, cv2.THRESH_BINARY)

# 查找轮廓,参数:源、组织已找到轮廓的模式、边框点保存模式,返回值:轮廓结果列表、层级
# 组织已找到轮廓的模式:RETR_EXTERNAL=0(只检测外轮廓)、RETR_LIST=1(检测到的轮廓不建立层级关系)、RETR_CCOMP=2(最多两层)、RETR_TREE=3(树形组织)
# 边框点保存模式:CHAIN_APPROX_NONE(保存所有轮廓上的点)、CHAIN_APPROX_SIMPLE(只保存角点)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 绘制轮廓,参数:源、轮廓(点)、需要绘制的轮廓的索引(-1表示所有)、颜色、线宽(-1表示全部填充)
contours_res = cv2.drawContours(ori_img, contours, -1, (0, 255, 0), 1)

cv2.imshow('binary', binary)
cv2.imshow('contours_res', contours_res)


cv2.waitKeyEx(0)

轮廓的面积和周长

import cv2

ori_img = cv2.imread('9.png')
img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(img, 140, 255, cv2.THRESH_BINARY)

contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours_res = cv2.drawContours(ori_img, contours, -1, (0, 255, 0), 1)

# 计算轮廓面积,参数:单一轮廓
area = cv2.contourArea(contours[0])

# 计算轮廓周长,参数:单一轮廓、是否闭合
length = cv2.arcLength(contours[0], True)

cv2.imshow('binary', binary)
cv2.imshow('contours_res', contours_res)


cv2.waitKeyEx(0)

多边形逼近与凸包

import cv2


def draw(img, points):
    for i in range(len(points)):
        if i == len(points) -1:
            next_one = points[0][0]
        else:
            next_one = points[i + 1][0]
        cv2.line(img, points[i][0], next_one, (0, 0, 255), 3)
        i += 1


ori_img = cv2.imread('10.png')
img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(img, 140, 255, cv2.THRESH_BINARY)

contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours_res = cv2.drawContours(ori_img, contours, -1, (0, 255, 0), 1)

# 多边形逼近,参数:轮廓(点)、精度(越小越贴合)、是否闭合
approx_res = cv2.approxPolyDP(contours[1], 20, True)
draw(ori_img, approx_res)
# 凸包,参数:轮廓(点)、顺逆时针
convex_res = cv2.convexHull(contours[2])
draw(ori_img, convex_res)

cv2.imshow('ori_img', ori_img)
# cv2.imshow('contours_res', contours_res)

cv2.waitKeyEx(0)

外接矩形

import cv2
import numpy as np

ori_img = cv2.imread('66.png')
img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(img, 140, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 最小外接矩形,参数:轮廓(点),返回值:RotatedRect(包含起始点(x,y)、宽高(w,h)、角度(angle))
min_r = cv2.minAreaRect(contours[0])
min_box = np.int0(cv2.boxPoints(min_r))
cv2.drawContours(ori_img, [min_box], 0, (0, 255, 0), 3)
# 最大外界矩形,参数:轮廓(点),返回值:Rect(包含起始点(x,y)、宽高(w,h))
x, y, w, h = cv2.boundingRect(contours[0])
cv2.rectangle(ori_img, (x, y), (x + w, y + h), (0, 0, 255), 3)

cv2.imshow('ori_img', ori_img)

cv2.waitKeyEx(0)

标签:des,img,imshow,cv2,笔记,opencv,np,import
From: https://www.cnblogs.com/missfxy/p/16953212.html

相关文章

  • NVIDIA Jetson TX2安装opencv4.1
    mkdirbuildvimcv_cmake.sh#!/bin/bashcmake\-DCMAKE_BUILD_TYPE=Release\-DCMAKE_INSTALL_PREFIX=/usr\-DBUILD_PNG=OFF\......
  • Vue2(笔记21) - 组件 - 组件的嵌套
    组件的嵌套官方的图中,就可以看出,组件之间是可以嵌套的;没有嵌套的组件为了方便,就直接把前面写好的拿来用了;<divid="root"><h1>{{msg}}</h1><hr><school></schoo......
  • Vue2(笔记19) - 组件 - 对组件的理解
    传统方式写应用传统方式做项目:一个页面一个html,每个页面都会引入几个js 和css,代码交叉复制、文件交叉引用;存在的问题:1)依赖关系混乱,不好维护;2)代码复用率不高;模块化:理解:......
  • [笔记]java分析内存
    分析内存1.jmap_dump2.下载地址https://www.ej-technologies.com/download/jprofiler/files2.1JVM启动参数-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=D:\heap......
  • Vue2(笔记20) - 组件 - Vue 非单文件组件 和 几个注意点
    Vue 非单文件组件非单文件组件:一个文件中包含N个组件;单文件组件:一个文件中只包含有1个组件,以 XXX.vue 为组件文件,需要打包;传统做法<divid="root"><h2>学校名称:{{sch......
  • CISAW风险管理学习笔记(7)-项目管理基础和环境建立
    个人学习总结,CISAW学习笔记之项目管理基础和环境建立:......
  • DevOps运维开发一体化 - 公开课笔记
    DevOps运维开发一体化DevOps核心思想:最大化提升工作效率,通过一系列技术栈来体现。开发人员产品经理测试人员运维人员…分部门的传统的开发方式,开发周期一般比较长,部门比......
  • react前端优化小结笔记
    编译阶段的优化主要是webpack开发环境时重复构建更快1.include缩小编译的范围rules:[{test:/\.js$/,use:[{loader:'babel-loader',opt......
  • NLP思维一书读书笔记
     关于NLP,我先给出比较正规的解释。再给出我个人的解释。——————————正规解释——————————NLP是神经语言程序学的英文缩写。在香港,也有意译为身心......
  • 图像处理技术OpencvSharp入门
    目录第一部分初识Opencv1.C#下Opencv库2.安装OpenCvSharp第二部分OpencvSharp入门1.加载图像文件2.显示图像第三部分基础应用1.颜色转换2.尺寸调整3.二值化......