图像灰度化
什么是图像灰度化?
图像灰度化并不是将单纯的图像变成灰色,而是将图片的BGR各通道以某种规律综合起来,使图片显示位灰色。
规律如下:
手动实现灰度化
首先我们采用手动灰度化的方式:
其思想就是:
先创建一个跟原来长宽一样的空白图片,然后将原图片中图片各个像素按照下面公式填入图片中,实现灰度化。
import cv2
import numpy as np
from skimage.color import rgb2gray
from PIL import Image
import matplotlib.pyplot as pltimg = cv2.imread("lenna.png") #opencv读取图像
#img = plt.imread("lenna.png") #matlab读取图像
h,w = img.shape[:2] #读出图像的长宽
img_gray = np.zeros([h,w],img.dtype) #创建一个与当前图像相同长宽的单通道图片
for i in range(h):for j in range(w):m = img[i,j]img_gray[i,j] = int(m[0]*0.11+m[1]*0.59+m[2]*0.3) #将CV读取的BGR转化为gray值给新图像print(img_gray)
cv2.imshow('gray picture ',img_gray) #cv展示灰色图像
cv2.waitKey (0) #如果不写等待时间,图像会一闪而过
skimage实现图像灰度化
img = cv2.imread("lenna.png")
img_gray = rgb2gray(img)
cv2.imshow('gray picture ',img_gray)
cv2.waitKey (0)
opencv实现图像灰度化
img = cv2.imread("lenna.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#用opencv输出
cv2.imshow('gray picture ',img_gray)
cv2.waitKey (0)#用plt输出:这里要注意,cmap为颜色图谱,默认为RGB(A)颜色空间,也可以指定,gray是灰度图,若cmap为其他会造成色差
plt.imshow(img_gray,cmap="gray")
plt.show()
图像二值化
什么是图像二值化?
所谓图像二值化,就是将图像中像素点的值取其中间值,若大于中间值,则将该像素点的值设为最大值,若小于中间值,则把该像素点设为最小值。使整个图片最后只存在两个值:最大值和最小值。
手动实现二值化
img = plt.imread("lenna.png")
img_gray = rgb2gray(img) #这里还是要先灰度化
rows, cols = img_gray.shape
for i in range(rows):for j in range(cols):if (img_gray[i, j] <= 0.5):img_gray[i, j] = 0else:img_gray[i, j] = 1plt.imshow(img_gray,cmap="gray")
plt.show()
numpy实现图像二值化
img = plt.imread("lenna.png")
img_gray = rgb2gray(img)#这里还是要先灰度化img_binary = np.where(img_gray >= 0.5, 1, 0)
plt.imshow(img_binary,cmap="gray")
plt.show()
opencv实现图像二值化
img = cv2.imread("lenna.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#这里还是要先灰度化cv2.threshold(img_gray,127,255,0,img_gray)
cv2.imshow('img_binary',img_gray)
cv2.waitKey(0)
全部代码与实现结果:
全部代码:
import cv2
import numpy as np
from skimage.color import rgb2gray
from PIL import Image
import matplotlib.pyplot as plt"""
手动实现图像灰度化
"""img = cv2.imread("lenna.png") #opencv读取图像
#img = plt.imread("lenna.png") #matlab读取图像
h,w = img.shape[:2] #读出图像的长宽
img_gray = np.zeros([h,w],img.dtype) #创建一个与当前图像相同长宽的单通道图片
for i in range(h):for j in range(w):m = img[i,j]img_gray[i,j] = int(m[0]*0.11+m[1]*0.59+m[2]*0.3) #将CV读取的BGR转化为gray值给新图像,注意:这个公式是内定的print(img_gray)
cv2.imshow('gray picture ',img_gray) #cv展示灰色图像
cv2.waitKey (0) #如果不写等待时间,图像会一闪而过"""
skimage实现图像灰度化
"""img = cv2.imread("lenna.png")
img_gray = rgb2gray(img)
cv2.imshow('gray picture ',img_gray)
cv2.waitKey (0)"""
opencv实现图像灰度化
"""img = cv2.imread("lenna.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#用opencv输出
cv2.imshow('gray picture ',img_gray)
cv2.waitKey (0)plt.imshow(img_gray,cmap="gray")
plt.show()"""
手动图像二值化
"""
img = plt.imread("lenna.png")
img_gray = rgb2gray(img)
rows, cols = img_gray.shape
for i in range(rows):for j in range(cols):if (img_gray[i, j] <= 0.5):img_gray[i, j] = 0else:img_gray[i, j] = 1plt.imshow(img_gray,cmap="gray")
plt.show()"""
numpy实现图像二值化
"""
img = plt.imread("lenna.png")
img_gray = rgb2gray(img)
img_binary = np.where(img_gray >= 0.5, 1, 0)
plt.imshow(img_binary,cmap="gray")
plt.show()"""
opencv实现图像二值化
"""img = cv2.imread("lenna.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.threshold(img_gray,127,255,0,img_gray)
cv2.imshow('img_binary',img_gray)
cv2.waitKey(0)
实现结果:
原图:
灰度化:
二值化:
思考与问题:
1.二值化中plt与cv阈值不同问题:
在plt读取图像之后,图像的每一个像素值都在[0,1]之间,在之后的cv2读取的图像,每一个像素值在[0,255]之间,所以在二值化时,plt是阈值为0.5,像素值分成0或1,而cv2中阈值是127,像素值分为0或255。
2.plt与cv交叉读取数据会出现图像失真问题:
因为 opencv 的接口使用BGR模式,而 matplotlib.pyplot 接口使用的是RGB模式
解决方法是:
在cv输入图像后把通道顺序变换一下,就在cv2.imread输入后面添加
b, g, r = cv2.split(img)
img = cv2.merge([r, g, b])
3.在灰度化和二值化图像用plt输出的时候必须添加cmap = ‘gray’,如果图像会失真
用plt输出中cmap为颜色图谱,默认为RGB(A)颜色空间,也可以指定,gray是灰度图,若cmap为其他会造成色差
4.CV或者plt打印图像时很快消失:
无论谁cv输出还是plt输出的最后的结尾都需要加上cv.waitkey(0)
或者plt.show()
不然输出图像转瞬即逝,很快就消失了,不能长时间停留。
5.PLT和openCV读取和输出方法:
PLT:
#输入
img = plt.imread("lenna.png")
#输出
plt.imshow(img,cmap="gray")
plt.show()
CV:
#输入
img = cv2.imread("lenna.png")
#输出
cv2.imshow('img',img_gray)
cv2.waitKey(0)
这里注意:cv2的输出必须有标题,不然会报错。