Opencv中cv2.cvtColor彩色图转灰度图的其他6种方法
Opencv是一种计算机视觉库,可以在Python、C++等多个编程语言中使用。其中,cv2.cvtColor函数可以将彩色图片转换为灰度图。除了cv2.cvtColor函数,还有其他6种方法可以实现彩色图转灰度图,本文将介绍这些方法。
1. 加权平均法
加权平均法是最简单的一种思路,即将原图中每个像素的RGB值进行加权平均,求得一个灰度值。一般情况下,R、G、B三个通道的权重为0.3、0.59、0.11。
代码如下:
import cv2
img = cv2.imread('color_img.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 加权平均法,求得灰度图
gray_img_wa = img[..., 0] * 0.3 + img[..., 1] * 0.59 + img[..., 2] * 0.11
cv2.imshow('Original', img)
cv2.imshow('cv2.cvtColor', gray_img)
cv2.imshow('Weighted Average', gray_img_wa)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下图所示:

从结果可以看出,加权平均法求得的灰度图和cv2.cvtColor方法得到的灰度图几乎一样,但是加权平均法比cv2.cvtColor方法稍微耗时一些。
2. 最大值法
最大值法是将原图中每个像素的RGB值求最大值作为该像素的灰度值。代码如下:
import cv2
import numpy as np
img = cv2.imread('color_img.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 最大值法,求得灰度图
gray_img_max = np.max(img, axis=2)
cv2.imshow('Original', img)
cv2.imshow('cv2.cvtColor', gray_img)
cv2.imshow('Maximum', gray_img_max)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下图所示:

从结果可以看出,最大值法得到的灰度图比其他方法得到的灰度图更为清晰,但也更严谨,可能会失去一些图像信息。
3. 最小值法
最小值法是将原图中每个像素的RGB值求最小值作为该像素的灰度值。代码如下:
import cv2
import numpy as np
img = cv2.imread('color_img.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 最小值法,求得灰度图
gray_img_min = np.min(img, axis=2)
cv2.imshow('Original', img)
cv2.imshow('cv2.cvtColor', gray_img)
cv2.imshow('Minimum', gray_img_min)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下图所示:

从结果可以看出,最小值法得到的灰度图相较于其他方法得到的灰度图更模糊一些。
4. 平均值法
平均值法是将原图中每个像素的RGB值求平均值作为该像素的灰度值。代码如下:
import cv2
import numpy as np
img = cv2.imread('color_img.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 平均值法,求得灰度图
gray_img_avg = np.mean(img, axis=2)
cv2.imshow('Original', img)
cv2.imshow('cv2.cvtColor', gray_img)
cv2.imshow('Average', gray_img_avg)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下图所示:

从结果可以看出,平均值法得到的灰度图比其他方法得到的灰度图更为灰暗。
5. 自适应阈值法
自适应阈值法是将原图分割成若干小块,然后分别计算每个小块中像素的灰度均值,作为该小块内的阈值,将小块内高于阈值的像素设置为255(白色),低于阈值的像素设置为0(黑色),最终合并成一张灰度图。
代码如下:
import cv2
img = cv2.imread('color_img.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 自适应阈值法,求得灰度图
gray_img_adp = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 8)
cv2.imshow('Original', img)
cv2.imshow('cv2.cvtColor', gray_img)
cv2.imshow('Adaptive Thresholding', gray_img_adp)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下图所示:

从结果可以看出,自适应阈值法得到的灰度图相较于其他方法得到的灰度图更为清晰,但会有一些噪点。
6. Sobel算子法
Sobel算子是一种常用的边缘检测算法,可以用来检测灰度图像中的边缘。其思路是将图像通过一个二阶偏导算子的卷积,求出图像水平和垂直方向的梯度,再将梯度平方和开方,形成一个较为粗略的边缘图。
代码如下:
import cv2
img = cv2.imread('color_img.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Sobel算子法,求得边缘图
sobel_x = cv2.Sobel(gray_img, cv2.CV_64F, 1, 0)
sobel_y = cv2.Sobel(gray_img, cv2.CV_64F, 0, 1)
gray_img_sobel = cv2.convertScaleAbs(cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0))
cv2.imshow('Original', img)
cv2.imshow('cv2.cvtColor', gray_img)
cv2.imshow('Sobel', gray_img_sobel)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下图所示:

从结果可以看出,Sobel算子法得到的边缘图并不是一张纯粹的灰度图,但可以用于去除图像中的噪点。
总结:
本文介绍了Opencv中彩色图转灰度图的其他6种方法,分别是加权平均法、最大值法、最小值法、平均值法、自适应阈值法、Sobel算子法。这些方法各有优缺点,可以根据实际应用场景选择使用。
