0%

【Opencv】基于色差的简单目标提取

  所有颜色都是由$R$(红)、$G$(绿)、$B$(蓝) 3个单色调配而成, 每种单色都人为地从$0~255$分成了$256$个级,所以根据$R$、 $G$、$B$的不同 组合可以表示$256×256×256=16777216$种颜色,被称为全彩色图像(full-color image)或者真彩色图像(true-color image)。一幅全彩色图像如果不压缩,文件将会很大。例如,一幅$640×480$像素的全彩色图像,一个像素由$3$个字节来表示$R$、 $G$、$B$各个分量,需要保存$640×480×3=921600$(约1MB)字节。
  对于自然界的目标提取,可以根据目标的颜色特征,尽量使用$R$、 $G$、$B$分量及它们之间的差分组合,这样可以有效避免自然光变化的影响,快速有效地提取目标。
  举例:要从果树上提取桃子的红色区域所在位置,如下面照片所示。
在这里插入图片描述
由于成熟桃子一般带红色,因此对彩色原图像首先利用红、绿色差信息提取图像中桃子的红色区域。对图像中的像素点($x_i$,$y_i$)($x_i$、$y_i$分别为像素点$i$的$x$坐标和$y$坐标,$0≤i0$,设灰度图像上该点的像素值为βi,否则为0(黑色)。之后做出$RG$图像的直方图找出谷点$α$(作为二值化的阈值)。逐像素扫描$RG$图像,若$β_i>α$,则将该点像素值设为$255$(白色),否则设为$0$(黑色),获得二值图像。然后再对图像进行形态学处理。
色差图:在这里插入图片描述
直方图:在这里插入图片描述
二值化:在这里插入图片描述
形态学处理:
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('peach.jpg', 1)
#因为cv2读取的照片类型是BGR类型,所以要转成RGB类型的照片
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#得到r, g, b通道的照片
r, g, b = cv2.split(img_rgb)
#获得RG灰度图像
c = r - g
#求出色差图的直方图,查看分割的最优阈值
hist, bins = np.histogram(c, bins = 256, range = (0, 256))
plt.plot(hist)
plt.show()
#采用190作为阈值
thresh_value = np.sum(c[np.where(c != 0)]) / np.sum(c != 0)
_, peach = cv2.threshold(c, 190, 255, cv2.THRESH_BINARY_INV)
#进行腐蚀操作,将小白点去除
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
peach = cv2.erode(peach, kernel, iterations = 3)