【1】引言
前序学习进程中,我们已经对阈值处理有所认知,相关文章链接为:
python学opencv|读取图像(三十三)阈值处理-灰度图像-CSDN博客
python学opencv|读取图像(三十四)阈值处理-彩色图像-CSDN博客
python学opencv|读取图像(三十五)反阈值处理-CSDN博客
综合的技能点为:
cv.THRESH_BINARY阈值处理的原则是:给定阈值开关,大于开关的像素点,对其BGR值强制赋最大值255,相反则赋0;
cv.THRESH_BINARY_INV反阈值处理的原则是: 给定阈值开关,大于开关的像素点,对其BGR值强制赋0,相反则赋最大值255。
如果有些时候无需赋最大值255,只需要赋最小值0,这时候就要做零值处理。
【2】官网教程
零值处理依然使用cv2.threshold()函数,只不过此时需要调用的Type参数换成了cv.THRESH_TOZERO或者cv.THRESH_TOZERO_INV,这两个参数的作用是:
cv.THRESH_TOZERO零值处理的原则是:给定阈值开关,不大于开关的像素点,对其BGR值强制赋最小值0,相反则保持原值;
cv.THRESH_TOZERO_INV反零值处理的原则是: 给定阈值开关,大于开关的像素点,对其BGR值强制赋0,相反则保持原值。
关于这两个参数的介绍,可以通过下述链接直达官网:
OpenCV: Miscellaneous Image Transformations
++图1++
【3】代码测试
【3.1】灰度图像
在上述分析的基础上,我们进行代码测试。
首先是引入模块和图像:
python
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块
# 读取图片
src = cv.imread('srcun.png',0)
dst=src#输出图像
然后进行零值处理和反零值处理:
python
#零值处理
t1,dst1=cv.threshold(src,58,158,cv.THRESH_BINARY_INV) #阈值开关58,阈值上限158
t2,dst2=cv.threshold(src,100,255,cv.THRESH_BINARY_INV) #阈值开关100,阈值上限255
t3,dst3=cv.threshold(src,0,255,cv.THRESH_BINARY_INV) #阈值开关0,阈值上限255
#反零值处理
tt1,dstt1=cv.threshold(src,58,158,cv.THRESH_BINARY_INV) #阈值开关58,阈值上限158
tt2,dstt2=cv.threshold(src,100,255,cv.THRESH_BINARY_INV) #阈值开关100,阈值上限255
tt3,dstt3=cv.threshold(src,0,255,cv.THRESH_BINARY_INV) #阈值开关0,阈值上限255
之后将零值处理图像和原图像进行对比:
python
#零值处理
t1,dst1=cv.threshold(src,58,158,cv.THRESH_TOZERO) #阈值开关58,阈值上限158
t2,dst2=cv.threshold(src,100,255,cv.THRESH_TOZERO) #阈值开关100,阈值上限255
t3,dst3=cv.threshold(src,0,255,cv.THRESH_TOZERO) #阈值开关0,阈值上限255
#反零值处理
tt1,dstt1=cv.threshold(src,58,158,cv.THRESH_TOZERO_INV) #阈值开关58,阈值上限158
tt2,dstt2=cv.threshold(src,100,255,cv.THRESH_TOZERO_INV) #阈值开关100,阈值上限255
tt3,dstt3=cv.threshold(src,0,255,cv.THRESH_TOZERO_INV) #阈值开关0,阈值上限255
之后就是显示特定点的BGR值,保存图像:
python
#显示BGR值
print("dst像素数为[100,100]位置处的BGR=", dst[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst1像素数为[100,100]位置处的BGR=", dst1[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst2像素数为[100,100]位置处的BGR=", dst2[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst3像素数为[100,100]位置处的BGR=", dst3[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt1像素数为[100,100]位置处的BGR=", dstt1[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt2像素数为[100,100]位置处的BGR=", dstt2[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt3像素数为[100,100]位置处的BGR=", dstt3[100, 100]) # 获取像素数为[100,100]位置处的BGR
#保存图像
cv.imwrite('srcf-m-VC-dst.png', dst) # 保存图像
cv.imwrite('srcf-m-t1-VC-ttt1.png', ttt1) # 保存图像
cv.imwrite('srcf-m-t2-VC-ttt2.png', ttt2) # 保存图像
cv.imwrite('srcf-m-t3-VC-ttt3.png', ttt3) # 保存图像
cv.waitKey() # 图像不会自动关闭
cv.destroyAllWindows() # 释放所有窗口
此处使用的原图为:
++图2++
读取图像时转化的灰度图为:
++图3++
按照原图-零值-反零值的顺序,进行零值和反零值处理后的图像效果对比图为:
++图4 原图-零值-反零值,阈值开关58++
++图5 原图-零值-反零值,阈值开关100++
++图6 原图-零值-反零值,阈值开关0++
从上述对比效果中,可以很明显地看出:零值处理后的图像,无论阈值开关多大,实际效果都相对于原图和反零值处理图更好。
看一下此时的特定像素点BGR值:
++图7 灰度图零值和反零值处理后的BGR值++
理论上分析,因为零值处理让本山RGB值小于阈值开关的像素点对应RGB=0,相当于让这些点直接变成黑点,而亮的地方保持不变,所以实际上是增强了对比效果。
此时的完整代码为:
python
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块
# 读取图片
src = cv.imread('srcun.png',0)
dst=src#输出图像
#零值处理
t1,dst1=cv.threshold(src,58,158,cv.THRESH_TOZERO) #阈值开关58,阈值上限158
t2,dst2=cv.threshold(src,100,255,cv.THRESH_TOZERO) #阈值开关100,阈值上限255
t3,dst3=cv.threshold(src,0,255,cv.THRESH_TOZERO) #阈值开关0,阈值上限255
#反零值处理
tt1,dstt1=cv.threshold(src,58,158,cv.THRESH_TOZERO_INV) #阈值开关58,阈值上限158
tt2,dstt2=cv.threshold(src,100,255,cv.THRESH_TOZERO_INV) #阈值开关100,阈值上限255
tt3,dstt3=cv.threshold(src,0,255,cv.THRESH_TOZERO_INV) #阈值开关0,阈值上限255
#和原图对比
ttt1=np.hstack((dst,dst1,dstt1)) #和原图对比
ttt2=np.hstack((dst,dst1,dstt2)) #和原图对比
ttt3=np.hstack((dst,dst1,dstt3)) #和原图对比
#展示图像
cv.imshow('srcf', dst) # 在屏幕展示效果
cv.imshow('srcft1', ttt1) # 在屏幕展示效果
cv.imshow('srcft2', ttt2) # 在屏幕展示效果
cv.imshow('srcft3', ttt3) # 在屏幕展示效果
#显示BGR值
print("dst像素数为[100,100]位置处的BGR=", dst[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst1像素数为[100,100]位置处的BGR=", dst1[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst2像素数为[100,100]位置处的BGR=", dst2[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst3像素数为[100,100]位置处的BGR=", dst3[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt1像素数为[100,100]位置处的BGR=", dstt1[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt2像素数为[100,100]位置处的BGR=", dstt2[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt3像素数为[100,100]位置处的BGR=", dstt3[100, 100]) # 获取像素数为[100,100]位置处的BGR
#保存图像
cv.imwrite('srcf-m-VC-dst.png', dst) # 保存图像
cv.imwrite('srcf-m-t1-VC-ttt1.png', ttt1) # 保存图像
cv.imwrite('srcf-m-t2-VC-ttt2.png', ttt2) # 保存图像
cv.imwrite('srcf-m-t3-VC-ttt3.png', ttt3) # 保存图像
cv.waitKey() # 图像不会自动关闭
cv.destroyAllWindows() # 释放所有窗口
【3.2】彩色图像
之后进行彩色图像的零值和反零值处理,这只需要改一行代码,将src = cv.imread('srcun.png',0)改为:
src = cv.imread('srcun.png') #读取图像
直接输出完整代码:
python
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块
# 读取图片
src = cv.imread('srcun.png') #读取图像
dst=src#输出图像
#零值处理
t1,dst1=cv.threshold(src,58,158,cv.THRESH_TOZERO) #阈值开关58,阈值上限158
t2,dst2=cv.threshold(src,100,255,cv.THRESH_TOZERO) #阈值开关100,阈值上限255
t3,dst3=cv.threshold(src,0,255,cv.THRESH_TOZERO) #阈值开关0,阈值上限255
#反零值处理
tt1,dstt1=cv.threshold(src,58,158,cv.THRESH_TOZERO_INV) #阈值开关58,阈值上限158
tt2,dstt2=cv.threshold(src,100,255,cv.THRESH_TOZERO_INV) #阈值开关100,阈值上限255
tt3,dstt3=cv.threshold(src,0,255,cv.THRESH_TOZERO_INV) #阈值开关0,阈值上限255
#和原图对比
ttt1=np.hstack((dst,dst1,dstt1)) #和原图对比
ttt2=np.hstack((dst,dst1,dstt2)) #和原图对比
ttt3=np.hstack((dst,dst1,dstt3)) #和原图对比
#展示图像
cv.imshow('srcf', dst) # 在屏幕展示效果
cv.imshow('srcft1', ttt1) # 在屏幕展示效果
cv.imshow('srcft2', ttt2) # 在屏幕展示效果
cv.imshow('srcft3', ttt3) # 在屏幕展示效果
#显示BGR值
print("dst像素数为[100,100]位置处的BGR=", dst[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst1像素数为[100,100]位置处的BGR=", dst1[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst2像素数为[100,100]位置处的BGR=", dst2[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dst3像素数为[100,100]位置处的BGR=", dst3[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt1像素数为[100,100]位置处的BGR=", dstt1[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt2像素数为[100,100]位置处的BGR=", dstt2[100, 100]) # 获取像素数为[100,100]位置处的BGR
print("dstt3像素数为[100,100]位置处的BGR=", dstt3[100, 100]) # 获取像素数为[100,100]位置处的BGR
#保存图像
cv.imwrite('srcf-m-VCC-dst.png', dst) # 保存图像
cv.imwrite('srcf-m-t1-VCC-ttt1.png', ttt1) # 保存图像
cv.imwrite('srcf-m-t2-VCC-ttt2.png', ttt2) # 保存图像
cv.imwrite('srcf-m-t3-VCC-ttt3.png', ttt3) # 保存图像
cv.waitKey() # 图像不会自动关闭
cv.destroyAllWindows() # 释放所有窗口
这里可以直接给出按照原图-零值-反零值的顺序的图像效果对比图:
++图8 原图-零值-反零值,阈值开关58++
++++
++图9 原图-零值-反零值,阈值开关100++
++++
++图10 原图-零值-反零值,阈值开关50++
看一下此时的特定像素点BGR值:
++图11 彩色图零值和反零值处理后的BGR值++
对于彩色图像也一样,理论上分析,因为零值处理让本身RGB值小于阈值开关的像素点对应RGB=0,相当于让这些点直接变成黑点,而亮的地方保持不变,所以实际上是增强了对比效果。
【4】细节说明
这里为了增强对比效果,所以调用了np.hstack()函数来让图像水平拼接;与此相对应,还有竖直拼接,可以调用np.vstack()函数实现这个目标。
【5】总结
掌握了python+opencv实现图像零值和反零值处理的技巧。