问题一:通道交换
读取图像,然后将通道替换成通道。
下面的代码用于提取图像的红色通道。
注意,cv2.imread()
的系数是按顺序排列的!
其中的变量red
表示的是仅有原图像红通道的imori.jpg
。
import cv2
img = cv2.imread("imori.jpg")
red = img[:, :, 2].copy()
blue=img[:,:,0].copy()
green=img[:,:,1].copy()
img_new=img.copy()
img_new[:, :, 0] = red
img_new[:, :, 1] = green
img_new[:, :, 2] = blue
plt.subplot(1,2,1),plt.imshow(img)
plt.subplot(122),plt.imshow(img_new)
问题二:灰度化(Grayscale)
将图像灰度化吧!
灰度是一种图像亮度的表示方法,通过下式计算:
import numpy as np
def BGR2GRAY(img):
b = img[:, :, 0].copy()
g = img[:, :, 1].copy()
r = img[:, :, 2].copy()
# Gray scale
out = 0.2126 * r + 0.7152 * g + 0.0722 * b
out = out.astype(np.uint8)
return out
img_BGR2GRAY=BGR2GRAY(img)
plt.subplot(1,2,1),plt.imshow(img)
plt.subplot(122),plt.imshow(img_BGR2GRAY)
问题三:二值化(Thresholding)
把图像进行二值化吧。
二值化是将图像使用黑和白两种颜色表示的方法。
我们将灰度的阈值设置为来进行二值化,即:
def BGR2GRAY(img):
b = img[:, :, 0].copy()
g = img[:, :, 1].copy()
r = img[:, :, 2].copy()
# Gray scale
out = 0.2126 * r + 0.7152 * g + 0.0722 * b
out = out.astype(np.uint8)
return out
# binalization
def binarization(img, th=128):
img[img < th] = 0
img[img >= th] = 255
return img
# Read image
img = cv.imread("imori.jpg")
# Grayscale
out1 = BGR2GRAY(img)
# Binarization
out = binarization(out1)
plt.subplot(1,3,1),plt.imshow(img)
plt.subplot(132),plt.imshow(out1)
plt.subplot(133),plt.imshow(out)
问题四:大津二值化算法(Otsu's Method)
使用大津算法来二值化图像吧。
大津算法,也被称作最大类间方差法,是一种可以自动确定二值化中阈值的算法。
从类内方差和类间方差的比值计算得来:
- 小于阈值的类记作,大于阈值的类记作;
- 和是被阈值分开的两个类中的像素数占总像素数的比率(满足);
- , 是这两个类中像素值的方差;
- ,是这两个类的像素值的平均值;
即:
- 类内方差:
- 类间方差:
- 图像所有像素的方差:
根据以上的式子,我们用以下的式子计算分离度:
也就是说: 换言之,如果使最大,就可以得到最好的二值化阈值。
def BGR2GRAY(img):
b = img[:, :, 0].copy()
g = img[:, :, 1].copy()
r = img[:, :, 2].copy()
# Gray scale
out = 0.2126 * r + 0.7152 * g + 0.0722 * b
out = out.astype(np.uint8)
return out
def otsu(image, th=127):
H,W=image.shape
max_sigma = 0
max_t = 0
# determine threshold
for _t in range(1, 255):
v0 = out[np.where(out < _t)]
m0 = np.mean(v0) if len(v0) > 0 else 0.
w0 = len(v0) / (H * W)
v1 = out[np.where(out >= _t)]
m1 = np.mean(v1) if len(v1) > 0 else 0.
w1 = len(v1) / (H * W)
sigma = w0 * w1 * ((m0 - m1) ** 2)
if sigma > max_sigma:
max_sigma = sigma
max_t = _t
# Binarization
print("threshold >>", max_t)
th = max_t
out[out < th] = 0
out[out >= th] = 255
return out
# Grayscale
out2 = BGR2GRAY(img)
# Otsu's binarization
out3 = otsu(out2)
plt.subplot(1,3,1),plt.imshow(img)
plt.subplot(132),plt.imshow(out2)
plt.subplot(133),plt.imshow(out3)