图片格式
- 在图像处理中,图像大致可以分为三种类型:黑白图像、灰度图像和彩色图像。
- 黑白图像中每个像素的值只有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 函数,如用于颜色分离的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 代表黑色。
- 扩展是指每个元素在一定范围内与周围元素进行或运算,并保持与原始值比较的变化。结果是白色部分扩大(黑色部分变小)到一定范围。
- 在下面的示例中,我们首先展开以去除白色矩形中的杂质。由于膨胀,图像变形(白色部分变大),然后我们进行侵蚀,使图像恢复到原来的形状。这时候我们发现白色矩形里面的黑点没有出现。然后我们再做一次腐蚀再膨胀,去掉左上角的白色杂质。
- 腐蚀核可以使用cv2.getStructingElement函数描述,具体可以参考这里(可以自己定义大小,核的大小决定每个像素的影响范围)
- 腐蚀可用函数cv2.erode函数,其参数内容可以参考这里
- interator参数越大越模糊(迭代次数越多越模糊)
- 膨胀可用函数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