(三)OpenCV之图像二值化

1 图像灰度化

1.0 Demo

import cv2
def grayImage(sourceDir):
	img = cv2.imread(sourceDir)
	cv2.imshow("Source Image", img)
	gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
	cv2.imshow("Gray image", gray)
	print("Image BGRA value: {}".format(img))
	print("Shape of PNG image: {}".format(img.shape))
	print("Image Gray value: {}".format(gray))
	print("Shape of gray image: {}".format(gray.shape))
sourceDir = "./images/reading/250.png"
grayImage(sourceDir)

1.2 Result

Image BGR value: [[[202 140   0]
  [202 140   0]
  [202 140   0]
  ...
  [202 140   0]
  [202 140   0]
  [202 140   0]]

 [[203 141   1]
  [203 141   1]
  [203 141   1]
  ...
  [203 141   1]
  [203 141   1]
  [203 141   1]]

 [[203 141   1]
  [203 141   1]
  [203 141   1]
  ...
  [203 141   1]
  [203 141   1]
  [203 141   1]]

 ...

 [[ 90 175  59]
  [ 90 175  59]
  [ 90 175  59]
  ...
  [ 92 179  51]
  [ 90 180  50]
  [ 88 179  52]]

 [[ 90 175  59]
  [ 90 175  59]
  [ 92 175  59]
  ...
  [ 92 179  52]
  [ 90 180  51]
  [ 88 179  54]]

 [[ 92 175  59]
  [ 92 175  59]
  [ 94 175  59]
  ...
  [ 90 176  58]
  [ 88 176  58]
  [ 88 176  58]]]
Shape of image: (250, 250, 3)
Image Gray value: [[105 105 105 ... 105 105 105]
 [106 106 106 ... 106 106 106]
 [106 106 106 ... 106 106 106]
 ...
 [131 131 131 ... 131 131 131]
 [131 131 131 ... 131 131 131]
 [131 131 131 ... 131 131 131]]
Shape of gray image: (250, 250)

处理的灰度图


在这里插入图片描述 Gray

图1.0 原图与灰度图

1.3 Analysis

  • imread()读取图片文件,并解码成整型数据,数据维度为(250,250,3),其中250,250为图片尺寸,3是图片通道数;
  • (250, 250, 3)数据为250x(250,3),三列数值分别为B,G,R通道数据;
  • BGR2GRAY计算:
    0.114 ∗ B + 0.587 ∗ G + 0.229 ∗ R 0.114*B+0.587*G+0.229*R 0.114B+0.587G+0.229R
  • GRAY数据维度为(250, 250);

2 图片二值化

2.1 直接二值化

2.1.0 Demo1

def directBinary(sourceDir):
	img = cv2.imread(sourceDir)
	cv2.imshow("Source Image", img)
	gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
	retval, dst = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
	print("Binary image value: {}".format(binary))
	print("Threshold value: {}".format(ret))
	cv2.imshow("Global Binary", binary)
	cv2.waitKey(0)
sourceDir = "./images/reading/250.png"
directBinary(sourceDir)

2.1.2 Result

Binary image value: [[255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]
 ...
 [255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]]
Shape of binary image value: (250, 250)
Threshold value: 0.0

全白的二值化图


在这里插入图片描述 white

图2.1 直接二值化

2.1.3 Demo2

def directBinary(sourceDir):
	img = cv2.imread(sourceDir)
	cv2.imshow("Source Image", img)
	gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
	retval, dst = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE)
	# 设置输出numpy.array的数量,如1e6,可以将省略号部分显示出来
	np.set_printoptions(threshold=1e6)
	print("Binary image value: {}".format(binary))
	print("Threshold value: {}".format(ret))
	cv2.imshow("Global Binary", binary)
	cv2.waitKey(0)
sourceDir = "./images/reading/250.png"
directBinary(sourceDir)

2.1.4 Result

Binary image value: [[0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]
Shape of binary image value: (250, 250)
Threshold value: 174.0

直接二值化处理


在这里插入图片描述 Direct

图2.2 联合Triangle算法二值化

2.1.5 Analysis

  • cv2.threshold(src, thresh, maxval, type)对应值(gray, 0, 255, cv2.THRESH_BINARY)或(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_BINARY),返回阈值revtal和处理的图像矩阵dst;
  • type:为阈值的计算方式,ThresholdTypes常用的有ThresholdBinary, Truncate, Value and Threshold Level等;
  • ThresholdBinary计算dst的公式为:
    d s t ( x , y ) = { m a x v a l , if src(x,y)>thresh 0 , otherwise dst(x,y)=\begin{cases} maxval, &\text{if src(x,y)>thresh} \\ 0, & \text {otherwise} \end{cases} dst(x,y)={maxval,0,if src(x,y)>threshotherwise
  • Demo1直接使用ThresholdBinary,返回矩阵全部为255,因为thresh设为0,maxval设为255,输入的gray矩阵像素值全小于255,所以返回白图一张;
  • Demo2使用ThresholdBinary和ThreshTriangle取或运算,ThresholdTriangle使用Triangle算法计算合适的阈值,本次计算为174.0,所以返回的dst以174为阈值进行分割,有0有225,返回黑白图;

2.2 自适应阈值二值化

2.2.1 Demo

def adaptiveBinary(sourceDir):
	img = cv2.imread(sourceDir)
	cv2.imshow("Source image", img)
	gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
	binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10)
	print("Binary image value: {}".format(binary))
	cv2.imshow("Adaptive image", binary)
	cv2.waitKey(0)
sourceDir = "./images/reading/250.png"
adaptiveBinary(sourceDir)

2.2.2 Result

Binary image value: [[255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]
 ...
 [255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]]

自适应处理


在这里插入图片描述 Adaptive

图2.3 自适应二值化

2.2.3 Analysis

  • cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)对应cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10)返回图像像素矩阵值dst;
  • 高斯自适应算法计算阈值ADAPTIVE_THRESH_GAUSSIAN_C;
  • 25为计算阈值取的像素面积,5x5也即卷积神经网络滑动窗口;
  • 10为计算的阈值减去的值;

2.3 均值二值化

2.3.1 Demo

def meanBinary(sourceDir):
	img = cv2.imread(sourceDir)
	cv2.imshow("Source image", img)
	gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
	y, x = gray.shape[:2]
	m = np.reshape(gray, (1, x*y))
	print("Reshape value: {}".format(m))
	print("Shape of reshape value: {}".format(m.shape))
	mean = m.sum()/(x*y)
	print("Mean of gray image value: {}".format(mean))
	retval, dst = cv2.threshold(gray, mean, 255, cv2.THRESH_BINARY)
	print("Retval value: {}".format(retval))
	cv2.imshow("Custom image", dst)
	cv2.waitKey(0)
sourceDir = "./images/reading/250.png"
meanBinary(sourceDir)

2.3.2 Result

Reshape value: [[105 105 105 ... 131 131 131]]
Shape of reshape value: (1, 62500)
Mean of gray image value: 130.606224
Retval value: 130.0

原图及二值图

Source Binary

图2.4 均值二值化

2.3.3 Analysis

  • 计算像素点均值mean作为阈值;
  • 使用THRESH_BINARY作为阈值类型,输出较好的反映了图片内容;

3 总结

  • 二值化步骤:读取图片imread    ⟹    \implies 灰度化cvtColor(img, cv2.COLOR_BGR2GRAY)    ⟹    \implies 二值化threshold;
  • 直接二值化,丢失信息过多,自适应二值化获取图形轮廓较全面,均值二值化类似于直接二值化;
  • OpenCV读取图片,输出三列数据分别为B,G,R;

[参考文献]
[1]https://www.cnblogs.com/FHC1994/p/9125570.html
[2]https://blog.csdn.net/wenhao_ir/article/details/51565517


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天然玩家

坚持才能做到极致

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值