opencv基本概念(图像格式、阈值分割(图像二值化)、膨胀腐蚀)

图片格式

  • 在图像处理中,图像大致可以分为三种类型:黑白图像、灰度图像和彩色图像。
  • 黑白图像中每个像素的值只有0(黑色)和 1(白色)
  • 灰度图像中每个像素的值则可取[0, 255],其中0 代表纯黑色,255 代表纯白
    颜色
  • 彩色图像通常具有三个通道。根据颜色描述空间的不同,彩色图像也有不同的格式。
  • RGB 颜色空间,即红绿蓝三原色,RGB 三个通道的取值范围都为[0, 255],
    彩色图像也可以看作是3 个灰度图像的合并。
  • Lab 颜色空间,L 值范围[0, 128]代表亮度;a 值范围[-128, 127],正数代表红色,负数代表绿色;b 值范围[-128, 127],正数代表黄色,负数代表蓝色。
  • HSV 颜色空间,色调(H),饱和度(S),明度(V)在不同应用场景中,HSV 取
    值范围不同
  • 使用 OpenCV 进行图像转换与通道分离

opencv基本概念(图像格式、阈值分割(图像二值化)、膨胀腐蚀)

  • 代码中用到的一些常见的opencv 函数,如用于颜色分离的cv2.inRange()函数可以参考这里
  • 直接通过cv2.imread()函数读取不同类型的图像,可以参考这里
  • 通过cv2.namedWindow()可以创建窗口,详细可以参考这里

代码

  • 本例程将进行 OpenCV 的图像转换与通道分离。
import cv2 #引用opencv功能包

#创建窗口,用于显示图片
cv2.namedWindow('MyWindow', cv2.WINDOW_NORMAL) # 使用该函数,使后面用同样名字的imshow显示的图片窗口可以改变大小

#提示停止方法
print ('Press key "Q" to stop.')
frame = cv2.imread('RGB.jpg',1) #以彩色图像格式读取图片
Quit = 1 #是否继续运行标志位

while Quit:
    keycode = cv2.waitKey(3)  # 每3ms刷新一次图片,同时读取3ms内键盘的输入
    if keycode&0xFF == ord('q'): #如果按下“Q”键,停止运行标志位置1,调出while循环,程序停止运行
        Quit = 0

    cv2.imshow('MyWindow', frame)  # 显示原图

    # RGB转灰度图像
    frame_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) #注意是BGRopencv读取图片的默认像素排列是BGR
    cv2.imshow('frame_gray', frame_gray)  # 直接imshow(),系统会自动执行nameWindow()创建窗口
    cv2.imwrite('gray.jpg', frame_gray)  # 保存灰度图像为文件

    # 灰度图像二值化处理获得黑白图像
    frame_binary = cv2.inRange(frame_gray,100,150) #图像中低于 100 的值,其所对应的图像值将为 0;图像中高于 150 的值,图像值变为 0 。
    # 换言之,源图像中仅有图像值介于 100 和 150 之间的值才不为 0 ,且值将变成 255
    cv2.imshow('frame_binary', frame_binary)  # 显示二值化图像
    cv2.imwrite('frame_binary.jpg', frame_binary)  # 显示二值化图像

    #RGB通道分离
    b,g,r = cv2.split(frame)
    # 显示三通道图像
    cv2.imshow('r', r)  # 二值化后的通道R
    cv2.imshow('g', g)  # 二值化后的通道G
    cv2.imshow('b', b)  # 二值化后的通道B

    # 分别保存三通道图片
    cv2.imwrite('r.jpg', r)
    cv2.imwrite('g.jpg', g)
    cv2.imwrite('b.jpg', b)

    # BGR转HSV颜色空间
    frame_HSV = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
    cv2.imshow('frame_HSV', frame_HSV)  # 显示图片
    cv2.imwrite('frame_HSV.jpg', frame_HSV)  # 保存图片

   # frame = cv2.imread('RGB.jpg', 1)  # 循环读取图片

print ('Quitted!') #提示程序已停止
cv2.destroyAllWindows() #程序停止前关闭所有窗口

阈值分割(图像二值化)

  • 阈值分割是一种图像分割技术,也称为阈值二值化
  • 阈值分割在灰度图像最常用的方法是取一个阈值分界值 Threshold,然后当任意一个像素点的灰度值高于Threshold时,该像素点的灰度值直接取值为255(该值可变),当任意一个像素点的灰度值低于Threshold时,该像素点的灰度值直接直接取值为 0
  • 二值化的主要作用是降低数据处理复杂程度,因为将 8 位(256)数据降低到了 1 位(0/1)数据,另一个作用则是高亮标示目标
  • 常用的二值化函数:Binary = cv2.threshold (Gray, 128, 255, cv2.THRESH_BINARY)
  • Gray代表输入的灰度图像,128为阈值,255代表灰度值大于阈值的像素点
    的灰度值会被设置为 255,cv2.THRESH_BINARY为二值化方法
  • 函数处理后,图像仍然是灰度图像,但图像只有两个灰度值,需要手动转换为二值(黑白)图像
  • 可以采用cv2.createTrackbar、cv2.getTrackbarPos设置进度条,并给进度条赋值。具体可以参考这里
  • 注意cv2.createTrackbar函数中的回调函数一定要有要设置一个输入参数,否则,在读取进度条的时候不会有值的变化
  • 通过cv2.bitwise_and对两幅图片图片按位取与,具体可以参考这里

代码

  • 本例程使用 OpenCV 对调用摄像头并进行动态阈值分割(两种二值化方法)
import cv2
import numpy as np

def callback(object):
    pass

#创建窗口
cv2.namedWindow('win1')

#提示停止方法
print ('Showing camera. Press key "Q" to stop.')

cameraCapture = cv2.VideoCapture(0) #创建读取摄像头的类
success,frame = cameraCapture.read() #读取第一帧图片,返回值为(是否成功读取, 图片)

#创建画布、窗口、进度条
canvas = np.zeros((170,600,3),dtype=np.uint8)+255  #创建画布放置阈值动态调节窗口
cv2.imshow("THRESHOLD",canvas)
cv2.createTrackbar("R_min","THRESHOLD",0,255,callback)#输入参数(参数名字,进度条附着窗口名字,进度条最小值,进度条最大值,回调函数)
cv2.createTrackbar("G_min","THRESHOLD",0,255,callback)
cv2.createTrackbar("B_min","THRESHOLD",0,255,callback)
cv2.createTrackbar("R_max","THRESHOLD",0,255,callback)
cv2.createTrackbar("G_max","THRESHOLD",0,255,callback)
cv2.createTrackbar("B_max","THRESHOLD",0,255,callback)

Quit = 1 #是否继续运行标志位
while success  and Quit :
    keycode = cv2.waitKey(1)
    if keycode&0xFF == ord('q'): #如果按下“Q”键,停止运行标志位置1,调出while循环,程序停止运行
        Quit = 0

    # 相关变量绑定进度条
    R_min = cv2.getTrackbarPos("R_min", "THRESHOLD") #获得进度条值
    G_min = cv2.getTrackbarPos("G_min", "THRESHOLD", )
    B_min = cv2.getTrackbarPos("B_min", "THRESHOLD", )
    R_max = cv2.getTrackbarPos("R_max", "THRESHOLD", )
    G_max = cv2.getTrackbarPos("G_max", "THRESHOLD", )
    B_max = cv2.getTrackbarPos("B_max", "THRESHOLD", )

    # 分别对RGB三通道进行二值化
    b, g, r = cv2.split(frame) #RGB通道分离
    cv2.imshow('r', r)  # 通道R
    cv2.imshow('g', g)  # 通道G
    cv2.imshow('b', b)  # 通道B
    frame_threshold_B = cv2.inRange(b, B_min, B_max)# 通道R二值化
    frame_threshold_G = cv2.inRange(g, G_min, G_max)  # 通道G二值化
    frame_threshold_R = cv2.inRange(r, R_min, R_max)  # 通道B二值化
    cv2.imshow('frame_threshold_R', frame_threshold_R)  # 窗口显示二值化后的通道R
    cv2.imshow('frame_threshold_G', frame_threshold_G)  # 窗口显示二值化后的通道G
    cv2.imshow('frame_threshold_B', frame_threshold_B)  # 窗口显示二值化后的通道B

    # 3通道二值化结果相与
    Binary_RGB_AND = cv2.bitwise_and(frame_threshold_R,frame_threshold_G) #相与
    frame_binary_manual = cv2.bitwise_and(frame_threshold_B,Binary_RGB_AND) # 最终结果
    cv2.imshow('frame_binary_manual', frame_binary_manual)  # 窗口显示彩色图像手动二值化结果

    # 直接对RGB图像进行二值化
    lower_rgb = np.array([B_min, G_min, R_min]) #注意这里是BGR,
    upper_rgb = np.array([B_max, G_max, R_max]) #因为opencv读取图片的默认像素排列是BGR
    frame_binary = cv2.inRange(frame,lower_rgb,upper_rgb)# 使用数组进行图像二值化

    cv2.imshow('win1', frame)  # 窗口显示原图
    cv2.imshow('frame_binary', frame_binary)  # 窗口显示对RGB图像进行二值化的结果

    success,frame = cameraCapture.read() #读取第一帧图片,返回值为(是否成功读取, 图片)

if success == 0: #提示由于摄像头读取失败停止程序
    print ('Camera disconnect !')
print ('Quitted!') #提示程序已停止
cv2.destroyAllWindows() #程序停止前关闭所有窗口
cameraCapture.release #程序停止前关闭摄像头调用
 

腐蚀膨胀

  • 膨胀腐蚀是图像处理中最基本也是最常用的操作。常用于去除图像中的杂质,在目标识别中常用于构建连通域进行抠图。
  • 二值图像可以当做一个值只有 0 和 1的矩阵,1 代表白色,0 代表黑色。
  • 扩展是指每个元素在一定范围内与周围元素进行或运算,并保持与原始值比较的变化。结果是白色部分扩大(黑色部分变小)到一定范围。
  • 在下面的示例中,我们首先展开以去除白色矩形中的杂质。由于膨胀,图像变形(白色部分变大),然后我们进行侵蚀,使图像恢复到原来的形状。这时候我们发现白色矩形里面的黑点没有出现。然后我们再做一次腐蚀再膨胀,去掉左上角的白色杂质。
    opencv基本概念(图像格式、阈值分割(图像二值化)、膨胀腐蚀)
  • 腐蚀核可以使用cv2.getStructingElement函数描述,具体可以参考这里(可以自己定义大小,核的大小决定每个像素的影响范围)
  • 腐蚀可用函数cv2.erode函数,其参数内容可以参考这里
  • interator参数越大越模糊(迭代次数越多越模糊)
    opencv基本概念(图像格式、阈值分割(图像二值化)、膨胀腐蚀)
  • 膨胀可用函数cv2.dilate函数

代码

  • 本demo可以插入到上一个例程中,整体展示效果
kernel_width=7 #膨胀腐蚀的范围大小
kernel_height=7 #膨胀腐蚀的范围大小
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(kernel_width,kernel_height)) #创建膨胀腐蚀核
frame_threshold_D = cv2.dilate(frame_binary,kernel) #膨胀
frame_binary_DE = cv2.erode(frame_binary_DE, kernel) #腐蚀
frame_binary_DE = cv2.erode(frame_binary_DE, kernel) #腐蚀
frame_binary_DE = cv2.dilate(frame_binary_DE, kernel) #膨胀

版权声明:本文为博主ljc_coder原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/m0_52785249/article/details/123290425

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2022年3月7日
下一篇 2022年3月7日

相关推荐