圖像灰度化
什么是圖像灰度化?
圖像灰度化并不是將單純的圖像變成灰色,而是將圖片的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的輸出必須有標題,不然會報錯。