opencv学习笔记

Core:包含OpenCV库的基础结构以及基本操作
Improc:包含基本的图像转换,包含滤波以及卷积操作
Highgui:包含可以用于显示图像或者进行简单输入的用户交互方法,可以看作是一个非常精良及的Windows UI工具包
Video:包含读取和写视频流的方法
Calib3d:包含校准单个、双目以及多个相机的算法实现
Featrue2d:包含用于检测、描述以及匹配特征点的算法
Objectect:包含检测特定目标的算法
ML:包含大量机器学习的算法
Flann:包含一些不回直接使用的方法,但是这些方法供其他模块使用
GPU:包含再CUDA GPU上优化实现的方法
Photo:包含计算摄影学的一些方法
Stitching:是一个精巧的图像拼接流程的实现

import cv2
import numpy as np
# 读取图片显示
# imread(path, flags) 
# flags: cv2.IMREAD_COLOR 读取彩色图片(不包含alpaha透明度) 可用1代替, 
# cv2.IMREAD_GRAYSCALE 读取灰度图片 可用0代替, cv2.IMREAD_UNCHANGED 读取完整图片 可用-1代替 (包含alpaha透明度)
img = cv2.imread(r'C:\Users\JX1402006\Desktop\web\55.PNG')  # 路径地址不能是中文
img.dtype  # 获取图片元素的类型
img.shape  # 获取图片的尺寸
img.size  # 获取图像尺寸 元素个数
605523
# 显示图像
# cv2.imshow(winname, mat)
# winname 显示窗口的名称
# mat 要显示的图像
cv2.imshow('img', img)
cv2.waitKey(0) # 用于等待用户按下键盘的时间,可获取ASCII码返回值 或者填写图像显示的时间
cv2.destroyAllWindows()  # 用于销毁所有正在显示的图像窗口
# 保存图像
# cv2.imwrite(filename, img)
# filename 保存图像所用的完整路径
# 确认某个像素的坐标[y, x]
# 获取像素
px = img[:20,:10] # 获取像素的RGB值
print(px)
# B = px[0]
# G = px[1]
# R = px[2]
# px = [255, 255, 255]
# for p in px:
#     p = [0,0,0]
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
[[[250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 247 247]
  [250 247 247]]

 [[250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 247 247]
  [250 247 247]
  [250 247 247]
  [250 247 246]]

 [[250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 247 247]
  [250 247 247]
  [250 247 246]
  [250 247 246]]

 [[250 248 247]
  [250 248 247]
  [250 248 247]
  [250 248 247]
  [250 247 247]
  [250 247 247]
  [250 247 246]
  [250 247 246]
  [250 247 246]
  [249 247 246]]

 [[250 248 247]
  [250 248 247]
  [250 247 247]
  [250 247 247]
  [250 247 247]
  [250 247 246]
  [250 247 246]
  [250 247 246]
  [249 247 246]
  [249 247 246]]

 [[250 248 247]
  [250 247 247]
  [250 247 247]
  [250 247 246]
  [250 247 246]
  [250 247 246]
  [250 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]]

 [[250 247 247]
  [250 247 247]
  [250 247 246]
  [250 247 246]
  [250 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]]

 [[250 247 247]
  [250 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]]

 [[250 247 246]
  [250 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]]

 [[249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]]

 [[249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 246 246]]

 [[249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 246 245]]

 [[249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 246 246]
  [249 246 246]
  [249 246 245]]

 [[249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]]

 [[249 247 246]
  [249 247 246]
  [249 247 246]
  [249 247 246]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]]

 [[249 247 246]
  [249 247 246]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]]

 [[249 247 246]
  [249 247 246]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]]

 [[249 246 246]
  [249 246 246]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]]

 [[249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]]

 [[249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]
  [249 246 245]]]
# 色彩转换
# dst = cv2.cvtColor(src, code)
# dst 转换后的图像
# src 需转换的图像
# code 转换码  cv2.COLOR_BGR2GRAY 将BGR转换到GRAY  cv2.COLOR_GRAY2BGR 将GRAY转换为BGR
dst = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('pic', dst) 
cv2.waitKey(0)
cv2.destroyAllWindows()
# HSV 色彩控件
# H 色调 区间[0,180]
# S 饱和度 区间[0,255]
# V 明暗 区间[0, 255]
dst = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 通道拆分
# b,g,r = cv2.split(bgr_mage)
# b 表示B通道的图像
b,g,r = cv2.split(img)
cv2.imshow('B', b)
cv2.waitKey(0)
cv2.destroyAllWindows()
# h,s,v = cv2.split(hsv_image)
# h 表示h的图像
h,s,v = cv2.split(dst)
print(h)

[[110 110 110 ... 113 113 113]
 [110 110 110 ... 113 113 113]
 [110 110 110 ... 113 113 113]
 ...
 [  0   0   0 ...   0   0   0]
 [  0   0   0 ...   0   0   0]
 [  0   0   0 ...   0   0   0]]
# alpha通道
bgra = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
b,g,r,a = cv2.split(bgra)
new_bgra = cv2.merge([b,g,r,a])
# 通道合并
# bgr = cv2.merge([b,g,r])
# b,r,g分别表示BRG通道上的图像

# 使用numpy创建图像
import numpy as np
import cv2
img = np.zeros((300, 400), dtype=np.uint8)
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 创建图像
img = np.full((300,400), 255, dtype=np.uint8)
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 创建内部由白色区域的图像
img = np.zeros((300,400), dtype=np.uint8)
img[100:150, 100:150] = 255
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 创建黑白相间的图像
img = np.zeros((300,400), dtype=np.uint8)
for i in range(int(300 / 40)):
    img[i * 40:i* 40+20,:] = 255
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 创建彩色图像
img = np.zeros((300,400, 3), dtype=np.uint8)
img[:,:,2] = 255
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 创建随机图像
img = np.random.randint(0, 255, size=(300, 400, 3),dtype=np.uint8)
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 拼接图像
# 水平拼接  array = np.hstack(tuple)  
n1 = np.array([1,2,3,4])
n2 = np.array([3,4,5, 6])
n3 = np.hstack((n1,n2))
print(n3)
# 垂直拼接 array = np.vstack(tuple)
n4 = np.vstack((n1,n2))
print(n4)
# 图像拼接
img1 = np.zeros((300,400), dtype=np.uint8)
img2 = np.full((300, 400), 255, dtype=np.uint8)
img3 = np.vstack((img1, img2))
cv2.imshow('pic', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
[1 2 3 4 3 4 5 6]
[[1 2 3 4]
 [3 4 5 6]]
# 绘制图像
# 绘制直线
# cv2.line(img, pt1, pt2, color, thickness)
# pt1, pt2 分表表示起点和终点的坐标
img = np.zeros((300, 400), dtype=np.uint8)
cv2.line(img, (0, 0), (100,100), (255, 255, 255), 3)

# 绘制矩形
# cv2.rectangle(img, pt1, pt2, color, thickness)
# pt1, pt2 分别表示矩形的左上角和右下角坐标
# 若thickness为-1 则表示绘制一个是实心的矩形
cv2.rectangle(img, (100, 100), (200, 200), (255,255,255), -1)

# 绘制圆
# cv2.circle(img, center, radius,color, thickness)
# center表示圆的中心点
# radius表示圆的半径
# 若thickness为-1 则表示绘制一个是实心的圆
cv2.circle(img, (150,150), 100, (255, 255,255), 3)

# 绘制多边形
# cv2.polylines(img, pts, isClosed, color, thickness)
# pts 表示多边形各个顶点坐标组成的列表 是numpy数组
# isClosed 表示是否封闭
pts = np.array([[200, 200], [250, 200], [260, 250]], np.int32)
cv2.polylines(img, [pts], True, (255, 255, 255), 3)

# 文字绘制
# cv2.putText(img, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)
# text 表示要绘制的文字
# org 表示文字在画布上左下角的坐标
# FontFace 表示文字样式
# fontScale 表示字体大小
# linrType 线型
# bottomLeftOrigin 绘制文字的方向 True or False
cv2.putText(img, 'micropython', (150, 50), cv2.FONT_HERSHEY_TRIPLEX, 1, (255,255,255), 3)
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 绘制动态图像
import time

v_x = 10
v_y = 6
x = 100
y = 100
pos = (x, y)
r = 10
while True:
    if x >  (200 - r) or x < r:
        v_x = v_x * -1
    if y >  (200 - r) or y < r:
        v_y = v_y * -1
    x += v_x
    y += v_y
    pos = (x, y)
    img = np.ones((200, 200, 3), dtype=np.uint8) * 255
    cv2.circle(img, pos, r, (255, 255, 0), -1)
    cv2.imshow('pic', img)
    time.sleep(1 / 60)
    res = cv2.waitKey(1)
    if  res == ord('1'):
        break
cv2.destroyAllWindows()

# 阈值处理
# retval, dst = cv2.threshold(src, thresh, maxval,type)
# thresh 阈值
# maxval 阈值处理采用的最大值
# type  阈值处理类型  
# retval 处理时采用的阈值


# 二值化处理 cv2.THRESH_BINARY
img = cv2.imread(r'C:\Users\JX1402006\Desktop\web\55.PNG')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, dst = cv2.threshold(img,80, 255, cv2.THRESH_BINARY)

# 反二值化处理  cv2.THRESH_BINARY_INV 
ret, dst = cv2.threshold(img,80, 255, cv2.THRESH_BINARY_INV)
 
# 0处理  cv2.THRESH_TOZERO
ret, dst = cv2.threshold(img, 80, 255, cv2.THRESH_TOZERO)

# 超出0处理  cv2.THRESH_TOZERO_INV 
ret, dst = cv2.threshold(img, 80, 255, cv2.THRESH_TOZERO_INV)

# 截断处理 将大于阈值的像素值变为和阈值一样 其他保持不变  cv2.THRESH_TRUNC
ret, dst = cv2.threshold(img, 80, 255, cv2.THRESH_TRUNC)

cv2.imshow('pic', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 自适应处理
# dst = cv2.adaptiveThrashold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
# maxValue 阈值处理采用的最大值
# adaptiveMethod 自适应阈值的计算方法
# thresholdType 阈值处理类型 cv2.THRESH_BINARY 或者 cv2.THRESH_BINARY_INV
# blockSize 一个正方形区域的大小
# C 常量 阈值等于均值或者甲醛值减去这个常量

# cv2.ADAPTIVE_THRESH_MEAN_C 对一个正方形区域内的所有像素平均加权

dst = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 3)
cv2.imshow('pic', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# Otsu方法
# 自动寻找最合适的阈值
img = cv2.imread(r'C:\Users\JX1402006\Desktop\web\55.PNG')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, dst = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow('pic', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 几何变换
# 缩放
# dst = cv2.resize(src, dsize, fx, fy, interpolation)
# dsize 输出图像的大小
# fx 水平方向的缩放比例 使用时bsize必须是None
# fy 垂直方向的缩放比例 使用时bsize必须是None
# interpolation 缩放的插值方式 在图像缩小或方法时需要删减或补充像素,该参数可以指定哪种算法进行增减
dst = cv2.resize(img, (100, 200))

dst = cv2.resize(img, None, fx=2, fy=1)

# 翻转
# dst = cv2.flip(src, flipCode)
# fileCode 翻转类型 
# 0 表示沿X轴方向翻转
# 正数 表示沿Y轴方向翻转
# 负数 表示沿X轴,Y轴方向翻转
dst = cv2.flip(img, -1)
cv2.imshow('pic', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 仿射变换
# dst = cv2.warpAffine(src, M, dsize, flags, borderMode, dorderValue)
# M 表示一个2行3列的矩阵 根据此矩阵的值变换原图中的像素位置 M=[[a,b,c],[d,e,f]] M的元素类型为float32
# dsize 输出图像的大小
# flags 插值方式
# borderMode 边界类型
# borderValue 边界值
# 新X = 原X * a + 原Y * b + c
# 新Y = 原X * d + 原Y * e + f

# 水平平移
h, w, d = img.shape
M = np.array([[1, 0.2, 20], [0.1,1,30]], dtype=np.float32)
dst = cv2.warpAffine(img, M, (w, h))

# 旋转
# 通过修改M来进行旋转
# M = cv2.getRotationMatrix2D(center, angle,scale)
# center 表示旋转中心
# angle 旋转角度 正数表示逆时针旋转 负数表示顺时针旋转
# scale 缩放比例 浮点数
M = cv2.getRotationMatrix2D((w / 2, h / 2), 30, 0.8)
dst = cv2.warpAffine(img, M, (w, h))

# 倾斜
# M = cv2.getAffineTransform(src, dst)
# src 原图三个点的坐标 格式是3行2列的数组
# dst 倾斜后的三点坐标
M = cv2.getAffineTransform(np.array([[0,0], [w,0], [0, h]], dtype=np.float32), np.array([[20,0], [w,0], [0, h]], dtype=np.float32))
dst = cv2.warpAffine(img, M, (w, h))

# 透视
# dst = cv2.warpPerspective(src, M, dsize, flags, borderMode, dorderValue)
# M 表示一个3行3列的矩阵 根据此矩阵的值变换原图中的像素位置 M=[[a,b,c],[d,e,f],[g,h,i]] M的元素类型为float32
# dsize 输出图像的大小
# flags 插值方式
# borderMode 边界类型
# borderValue 边界值
# M = cv2.getPerspectiveTransform(src, dst)
M = cv2.getPerspectiveTransform(np.array([[0, 0], [w, 0], [0,h], [w, h]], dtype=np.float32), np.array([[20, 0], [w-20, 0], [0,h], [w, h]], dtype=np.float32))
dst = cv2.warpPerspective(img, M, (w, h))
cv2.imshow('pic', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图像运算
# 掩模 ROI mask
# 图像加法运算
# dst = cv2.add(src1,src2, mask, dtype)  像素相加如果值超过255则取值255
# mask 掩膜
# dtype 图像深度

img = cv2.imread(r'C:\Users\JX1402006\Desktop\web\55.PNG')
h, w, d = img.shape
img2 = np.zeros((h, w, 3),dtype=np.uint8)
img2[100:200, 100:200] = [255, 255, 255]
dst = cv2.add(img, img2)


# 位运算符
# cv2.bitwise_and() 与  
# dst = cv2.bitwise_and(src1,src2,mask)
# 如果某像素和纯白像素与运算,结果是原像素; 如果和纯黑像素与运算,结果是纯黑

# cv2.bitwise_or()  或   
# dst = cv2.bitwise_or(src1,src2,mask)
# 如果某像素和纯白像素与运算,结果是纯白像素; 如果和纯黑像素与运算,结果是原像素

# cv2.bitwise_not() 取反
# dst = cv2.bitwise_or(src,mask)

# cv2.bitwise_xor() 异或
# dst = cv2.bitwise_xor(src1,scr2,mask)
# 如果某像素和纯白像素与运算,结果是原像素的取反; 如果和纯黑像素与运算,结果是原像素
img3 = np.zeros((h, w, 3),dtype=np.uint8)
dst = cv2.bitwise_xor(img, img2)
cv2.imshow('pic', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()


# 合并图像
# 加权和
# 加权和不会像纯加法那样让图像丢失信息,而是尽量保留原有图像信息的基础上把两幅图像融合
# dst = cv2.addWeighted(src1,alpha,src2, beta,gamma)
# alpha 第一幅图像的权重
# beta 第二幅图像的权重
# gamma 在结果上添加的标量,值越大结果图像越明亮, 可以是负数
img4 = cv2.imread(r'C:\Users\JX1402006\Desktop\web\66.PNG')
dst = cv2.addWeighted(img, 0.5, img3, 0.5, 0)


# 覆盖
# 将第二张图的信息直接覆盖到第一张图上
img[100:200,100:200,:] = img4[100:200, 100:200, :]

cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 滤波器
# 均值滤波器 将滤波核的进行平均求值
# dst = cv2.blur(src,ksize,anchor,borderType)
# ksize 滤波核大小,滤波核越大,处理后的图像越不清晰
# anchor 可选参数 滤波核的锚点 
# borderType 可选参数 边界样式
img = cv2.imread(r'C:\Users\JX1402006\Desktop\web\66.PNG')
dst = cv2.blur(img, (3,3))
cv2.imwrite( r'C:\Users\JX1402006\Desktop\web\label\77.png', dst)

# 中值滤波 将滤波核的数据进行排序,获取中间值
# dst = cv2.medianBlur(src, ksize)
# ksize必须是大于1的奇数
dst = cv2.medianBlur(img, 3)

# 高斯滤波器
# dst = cv2.GaussianBlur(src,ksize,sigmaX,sigmaY,borderType)
# sigmaX 卷积核水平方向的标准差
# sigmaY 卷积核垂直方向的标准差
# 如果sigmaX核sigmaY都为0,则会自动计算合适的权重比例
dst =  cv2.GaussianBlur(img,(3,3),0,0)

# 双边滤波
# dst = cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace,borderType)
# sigmaColor 参与计算的颜色范围,这个值是像素颜色值与周围颜色值的最大差值,只有差值小于这个值时,周围的像素才会进行滤波计算
# d 以当前像素为中心的整个滤波区域的直径
# sigmaSpace 坐标控件的值 值越大说明参与计算的像素数量越多
cv2.imshow('pic', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 腐蚀
# 通过像素块(核)在图像中的移动,将图像边缘那些与核重合但又没有越过核心的像素点进行抹除
# dst = cv2.erode(src,kernel,anchor,iterations,borderType, borderValue)
# kernel 像素块(核) 一般用numpy创建的二维数组
# iterations 可选参数 腐蚀操作的迭代次数
# borderType 边界样式
# borderValue 边界值
n1 = np.ones((3,3), np.uint8)
dst = cv2.erode(img, n1)

# 膨胀
# 与腐蚀相反,通过像素块(核)在图像中的移动,核会将图像边缘补充新的像素
# dst = cv2.dilate(src, kernel, anchor, iterations, borderType, borderValue)
n1 = np.ones((3,3), np.uint8)
dst = cv2.dilate(dst, n1)

# 开运算
# 先进行腐蚀 然后进行膨胀

# 闭运算
# 先进行膨胀 然后进行腐蚀

# 形态学方法
# dst = cv2.morphologyEx(src, op, kernel, anchor, iterations, borderType, borderValue)
# op 操作类型
# cv2.MORPH_ERODE 腐蚀操作
# cv2.MORPH_DILATE 膨胀操作
# cv2.MORPH_OPEN 开运算  先腐蚀后膨胀
# cv2.MORPH_CLOSE 闭运算  先膨胀后腐蚀
# cv2.MORPH_GRADIENT 梯队运算  膨胀图减腐蚀图
# cv2.MORPH_TOPHAT 顶帽运算  原始图减开运算
# cv2.MORPH_BLACKHAT 黑帽运算  闭运算减原始图
cv2.imshow('pic', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图像检测
# contours, hierarchy = cv2.findContours(image,mode,methode)
# image 必须是8位的单通道二值图像
# mode 轮廓检索模式  
# cv2.RETR_EXTERNAL 只检测外轮廓
# cv2.RETR_LIST 检测所有轮廓,但不建立层次关系
# cv2.RETE_CCOMP 检测所有轮廓,并建立两级层次关系
# cv2.RETR_TREE 检测所有轮廓,并建立树状结构的层次关系
# methode 检测轮廓时使用的方法
# cv2.CHAIN_APPROX_NONE 存储轮廓上的所有点
# cv2.CHAIN_APPROX_SIMPLE 只保存水平\垂直或对角线轮廓的断点
# cv2.CHAIN_APPROX_TC89_L1 Ten-Chinl近似算法的一种
# cv2.CHAIN_APPROX_TC89_KCOS Ten-Chinl近似算法的一种
# contours: findContours() 方法得出的轮廓列表
# hierarchy findContours() 方法得出的层次关系

# image = cv2.drawContours(image, contours, contourIDx, color, thinckness, lineTypee, hierarchy, maxLevel, offse)
# contourIdx 绘制轮廓的索引
# lineTpyee 绘制轮廓的线形
# offse 可以改变绘制结果的偏移量
# maxLevel 绘制轮廓的层次深度,最深绘制第maxLevel层


img = cv2.imread(r'C:\Users\JX1402006\Desktop\web\66.PNG')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
t,binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# print(contours)
# dst = cv2.drawContours(img, contours,-1, (0,0,255), 3)

# 轮廓拟合
# 矩形包围框
# retval = cv2.boundingRect(array)
# array 轮廓数组
# retval 4个整数 分别表示左上角顶点的x,y 以及矩形的宽和高
x,y,w,h = cv2.boundingRect(contours[0])
cv2.rectangle(img, (x, y), (x+w, y+h), (0,0,255), 2)

# 圆形包围框
# center, radius = cv2.minEnclosingCircle(points)
# points 表示轮廓数组
# center 表示最小圆的圆心坐标
# radius 最小圆的包围框半径
center,radius = cv2.minEnclosingCircle(contours[0])
x,y = center
cv2.circle(img, (int(x), int(y)), int(radius), (0,0,255),2)

# 凸包
# 最接近轮廓的多边形
# hull = cv2.convexHull(points, clockwise,returnPoints)
# hull 凸包的阵点数组
# clockwise 可选参数 BOOL 为True时,凸包中点按顺时针排列 否则相反
# returnPoints 可选参数 BOOL 为True时返回坐标点 否则返回索引
hull = cv2.convexHull(contours[0])
cv2.polylines(img, [hull], True, (0,0,255), 3)

# Canny边缘检测
# edges = cv2.Canny(img, threshlod1,threshold2, apertureSize, L2gradient)
# threshold1 计算的第一个阈值 一般是最小阈值
# threshold2 计算的第二个阈值 一般是最大阈值
# apertureSize 可选参数 Sobel算子的孔径大小
# L2gradient 可选参数 计算图像梯度的标识,默认是False 为True表示采用更精确的算法进行计算
# edges 表示输出图像 二值化灰度图像
edges = cv2.Canny(img, 100, 200)

# 霍夫变换
# lines = cv2.HoughLinesP(img, rho,theta,threshold,minLineLength, maxLineGap)
# 只能检测二值图像
# rho 检测直线使用的半径步长 值为1表示检测所有可能的半径步长
# theta 搜索直线的角度 值为Π/180 表示搜索所有角度
# threshold 阈值 越小检测的直线越多
# minLineLength 线段的最小长度
# maxLineGap 线段之间的最小距离
# lines 检测线段的数组
lines = cv2.HoughLinesP(binary, 1, np.pi/180, 15, 100, 18)
# print(lines)
for line in lines:
    x1,y1,x2,y2 = line[0]
    cv2.line(img, (x1,y1),(x2,y2), (0,0,255),3)

# 圆环检测
# circles = cv2.HoughCircles(img, method, dp, minDist, param1, param2, minRadius, maxRadius)
# method 检测方法
# dp 累加器分辨率和原视图像分辨率之比的倒数, 
# minDist 圆心之间的最小距离
# param1 可选参数 Canny边缘检测使用的最大阈值
# param2 可选参数 检测圆环结果的投票数 值越大检测的圆越少 越精确
# circles 数组 包含圆心坐标和半径
circles = cv2.HoughCircles(binary, cv2.HOUGH_GRADIENT, 1, 70, 100, 25)
print(circle)
# for circle in circles[0]:
#     x,y, r = circle
#     cv2.circle(img, (x,y), r, (0,255,0), 3)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
100.0
# 模板匹配
# result = cv2.matchTemplate(img, temp1,method, mask)
# temp 模板图像 尺寸必须小于等于原视图像
# method 匹配方法
# mask 可选参数
# result 计算出的匹配结果

# 匹配方法
# cv2.TM_SQDIFF 平方差匹配 
# cv2.TM_SQDIFF_NORMED 标准平方差匹配
# cv2.TM_CCORR 相似度匹配
# cv2.TM_CCORR_NORMED 标准相似度匹配
# cv2.TM_CCOEFF 系数匹配
# cv2.TM_CCORFF_NORMED 标准系数匹配

# 目标匹配
# minValue,maxValue, minLoc, maxLoc = cv2.minMaxLoc(src, mask)
# minValue 匹配数组中的最小值
# maxValue 匹配数组中的最大值
# minLoc 匹配数组中最小值的坐标
# maxLoc 匹配数组中最大值的坐标(x,y)

img = cv2.imread(r'C:\Users\JX1402006\Desktop\web\66.PNG')
tmp = img[190:260, 20:100,:]
results = cv2.matchTemplate(img, tmp, cv2.TM_SQDIFF)

minValue, maxValue,minLoc,maxLoc = cv2.minMaxLoc(results)
x, y = minLoc
cv2.rectangle(img, (x,y), (x+80, y+70), (0,0,255),3)
cv2.rectangle(img, (20,190), (100, 260), (0,255,0),3)


cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 视频处理
# capture = cv2.VideoCapture(index)
# capture 要打开的摄像头
# index 摄像头索引
# 摄像头数量及其索引先后顺序由操作系统自身决定
# index=0 若是笔记本 默认是自带的摄像头
# 检测摄像头是否初始化成功 retval = capture.isOpened()

# 读取摄像头图像
# retval ,img = capture.read()

# 关闭摄像头
# capture.release()

capture = cv2.VideoCapture(0)
while True:
    
    if capture.isOpened():
        ret, img = capture.read()
        cv2.imshow('video', img)
        key = cv2.waitKey(1)
        if key == ord('1'):
            break
    else:
        break
cv2.destroyAllWindows()
capture.release()

# 播放视频文件
# video = cv2.VideoCapture(filename)
# video 要打开的视频
# filename 打开的文件名

# 获取视频文件的属性
# retval = cv2.VideoCapture.get(propID)
# propId 文件属性值
# cv2.CAP_PROP_POS_MSEC 视频文件播放时的当前位置 单位(ms)
# cv2.CAP_PROP_POS_FRAMES 帧的索引
# cv2.CAP_PROP_POS_AVI_RATIO 视频文件的相对位置 0表示开始播放,1表示播放结束
# cv2.CAP_PROP_FRAME_WIDTH 视频文件帧的宽度
# cv2.CAP_PROP_FRAME_HEIGHT 视频文件帧的长度
# cv2.CAP_PROP_FPS 帧速率
# cv2.CAP_PROP_FOURCC 用4个字符表示视频的编码格式
# cv2.CAP_PROP_FRAME_COUNT 视频文件的帧数
# cv2.CAP_PROP_FORMAT 
# cv2.CAP_PROP_CONVERT_RGB 是否应将图像转换为RGB
import cv2
video = cv2.VideoCapture(r'C:\Users\JX1402006\Desktop\web\107.mp4')
while video.isOpened():
    cv2.namedWindow('video', cv2.NORM_HAMMING)
    cv2.resizeWindow('video', 420, 300)
    ret,img = video.read()
    cv2.imshow('video', img)
    key = cv2.waitKey(1)
    if key == ord('1'):
        break
video.release()
cv2.destroyAllWindows()

---------------------------------------------------------------------------

error                                     Traceback (most recent call last)

~\AppData\Local\Temp\ipykernel_70264\1973234775.py in <module>
      9     cv2.resizeWindow('video', 420, 300)
     10     ret,img = video.read()
---> 11     cv2.imshow('video', img)
     12     key = cv2.waitKey(1)
     13     if key == ord('1'):


error: OpenCV(4.9.0) D:\a\opencv-python\opencv-python\opencv\modules\highgui\src\window.cpp:971: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'
# 保存视频文件
# obkect = cv2.VideoWriter(filename, fourcc,fps, frameSize)
# object.write(frame)
# object.release()
# frame 表示需要写入的帧
# object 是VideoWriter对象
# fourcc 表示视频的编码格式
# fps 帧速率
# frameSize 每一帧的大小
# cv2.VideoWriter_fourcc() I420表示未压缩的YUV颜色编码格式 PIMI表示MPEG-1编码格式 FLVI表示Flash编码格式
# 
# 人脸跟踪
# 创建级联分类器
# object = cv2.CascadeClassifier(filename)
# object 分类器对象
# results = object.detectMultiScale(img, scaleFactor,minNeighbors, flags, minSize, maxSize)
# scaleFactor 可选参数 扫描图像时缩放的比例
# minNeighbors 可选参数 每个区域至少保留多少检测结果才可以判定为人脸
# flags  可选参数
# minSize 可选参数 最小目标尺寸
# maxSize 可选参数 最大目标尺寸
# results 返回目标区域结果的数组 分别是左上角的xy 以及宽和高
capture = cv2.VideoCapture(0)
face = cv2.CascadeClassifier(r'D:\Data\Python\env\MT2\Lib\site-packages\cv2\data\haarcascade_eye_tree_eyeglasses.xml')
while capture.isOpened():
    ret,img = capture.read()
    results = face.detectMultiScale(img, 1.15)
    for i in results:
        x,y,w,h = i
        cv2.rectangle(img, (x,y), (x+w, y + h), (0,0,255), 3)
    cv2.imshow('video', img)
    key = cv2.waitKey(1)
    if key == ord('1'):
        break
capture.release()
cv2.destroyAllWindows()
    
### 人脸识别 ###
# 通过创建识别器 训练识别器 识别来进行识别
# Eigenfaces 人脸识别器
# recognizer = cv2.face.EigenFaceRecognizer_create(num_components,threshold)
# num_components 可选参数 PCA方法中保留的分量个数
# threshold 可选参数 人脸识别时使用的阈值
# recognizer 创建完的Eignenfaces人脸识别器对象

# recognizer.train(src,labels)
# src 用来训练的样本 图像大小必须一样
# labels 样本对应的标签 必须是整数的数组

# label,confidence = recognizer.predict(src)
#  label 与样本匹配最高的标签值
# confidence 匹配度最高的信用度评分


### Fisherfaces 人脸识别器 ###
# recognizer = cv2.face.FishFaceRecognizer_create(num_components, threshold)
# num_components 可选参数 PCA方法中保留的分量个数
# threshold 可选参数 人脸识别时使用的阈值
# recognizer 创建完的Fisherfaces人脸识别器对象

# recognizer.train(src,labels)
# src 用来训练的样本 图像大小必须一样
# labels 样本对应的标签 必须是整数的数组

# label,confidence = recognizer.predict(src)
#  label 与样本匹配最高的标签值
# confidence 匹配度最高的信用度评分


### LBPH人脸识别器 ###
# recognizer = cv2.face.LBPHFaceRecognizer_create(radius,neighbors,grid_x,grid_y,threshold)
# radius 可选参数 圆形局部二进制模式的半径
# neighbors 可选参数 圆形局部二进制模式的采样点数目
# grid_x 可选参数 水平方向上的单元格数
# grid_y 可选参数 垂直方向上的单元格数
# threshold 可选参数 人脸识别时的阈值

# recognizer.train(src,labels)
# src 用来训练的样本 图像大小必须一样
# labels 样本对应的标签 必须是整数的数组

# label,confidence = recognizer.predict(src)
#  label 与样本匹配最高的标签值
# confidence 匹配度最高的信用度评分




# 创建窗口,设置窗口大小
cv2.namedWindow('test', cv2.NORM_HAMMING)   # cv2.Norm_hamming 标准尺寸  创建一个名称为‘test’的窗口
cv2.resizeWindow('test', 640, 480)
while True:
    cv2.imshow('test', 0)  # 显示窗口  0表示窗口存在的时间  
    key = cv2.waitKey(0)  # 等待外部按键输入 0表示毫秒刷新
    if key == ord('q'):   # 如果按下q 退出窗口
        break
cv2.destroyAllWindows() # 注销窗口




(2, 2, 2)
# 打开摄像头
cv2.namedWindow('video', cv2.NORM_HAMMING)
fourcc = cv2.VideoWriter.fourcc(*'mp4v')  # 写入视频的格式
vm = cv2.VideoWriter(r'C:\Users\JX1402006\Desktop\web\123.mp4', fourcc, 20, (640, 480)) # 20表示帧数
vc = cv2.VideoCapture(0)  # 开启摄像头编号 0表示本地摄像头 1表示外接摄像头
while vc.isOpened():  # 检测摄像头如果打开
    ret, frame = vc.read()  # 读取摄像头数据  ret 表示状态  frame表示读取的信息
    if ret:
        cv2.imshow('video', frame)
        vm.write(frame)
        if cv2.waitKey(50) == ord('1'):
            break
    else:
        break
vm.release()
vc.release()
cv2.destroyAllWindows()

# print(img.shape)
print(img.reshape(560*280*3,))
cv2.namedWindow('pic', cv2.NORM_HAMMING)
# cv2.resizeWindow('pic', (640,480))
while True:  
    cv2.imshow('pic', img)
    key=cv2.waitKey(0)
    if key == ord('1'):
        break
cv2.destroyAllWindows()



[255 255 255 ... 255 255 255]
# 测试图像恢复技术

img = cv2.imread(r'C:\Users\JX1402006\Desktop\web\OK_4.bmp')
# h,w,d = img.shape
# 对图像进行放大
# dst = cv2.resize(img, (w * 2, h * 2))
# 对方法后的图像进行腐蚀处理
# n1 = np.ones((3,3), np.uint8)
# dst = cv2.wiener(img, 5, 5)
# print(img[300:301, 20:22, :])
cv2.line(img,(270,80), (280,80), (180,180,180), 3)
cv2.imwrite(r'C:\Users\JX1402006\Desktop\web\NG_6.bmp', img)
# cv2.imshow('pic', img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
True


  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值