一、彩色圖片直方圖
cv2.calcHist([image],[0],None,[256],[0.0,255.0])
該方法的所有參數都必須用中括號括起來!!!
參數一:傳入的圖片數據
參數二:用于計算直方圖的通道,這里使用的是灰度直方圖,所以就使用第一個通道,第一個通道下標是0
參數三:mask模板,這里沒有用,所以給個None
參數四:直方圖的橫坐標尺度size,表明直方圖分成多少份,或有多少個柱狀;256表示0-255總共256個灰度值
參數五:直方圖中各個像素的值0.0-255.0表明從0.0開始已知到255.0所以的像素都進行遍歷,因為灰度值只能是0-255之內
cv2.minMaxLoc(hist)
計算當前hist這個直方圖中的最小值、最大值、最小值對應的下標和最大值對應的下標
cv2.split(img)
圖像分解,將彩色圖片的RGB分解為R G B三個通道
import cv2
import numpy as np
def ImageHist(image,type):color = (255,255,255)#定義當前顏色為白色windowName = 'Gray'#定義一個windows窗體if type == 31:#藍色直方圖color = (255,0,0)windowName = 'B Hist'elif type == 32:#綠色直方圖color = (0,255,0)windowName = 'G Hist'elif type == 33:#紅色直方圖color = (0,0,255)windowName = 'R Hist'hist = cv2.calcHist([image],[0],None,[256],[0.0,255.0])#計算直方圖方法minV,maxV,minL,maxL = cv2.minMaxLoc(hist)#計算當前hist這個直方圖中的最大值、最小值以及其分別對應的下標histImg = np.zeros([256,256,3],np.uint8)for h in range(256):intenNormal = int(hist[h]*256/maxV)#將所有的像素值歸到0-256之間,將圖片上的像素進行歸一化操作cv2.line(histImg,(h,256),(h,256-intenNormal),color)cv2.imshow(windowName,histImg)return histImgimg = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
channels = cv2.split(img)# 圖像分解,將RGB圖片分解為R G B三個通道
for i in range(0,3):#遍歷顏色通道0、1、2ImageHist(channels[i],31+i)
cv2.waitKey(0)
效果圖如下:
二、直方圖均衡化
灰度圖片的直方圖均衡化
cv2.equalizeHist(gray)
灰度圖的均衡化方法,只需要傳入一個灰度圖即可,其實針對的是一個顏色通道,若是彩色圖片有三個顏色通道需要分三次進行均衡化
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/Aa.jpg',1)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#將彩色圖轉換為灰度圖
cv2.imshow('src',gray)
dst = cv2.equalizeHist(gray)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果圖如下(左原圖,右均衡化圖片):
彩色圖片的直方圖均衡化
cv2.split(img)
圖像分解,將彩色圖片的RGB分解為R G B三個通道
cv2.merge((bH,gH,rH))
將單一的顏色通道進行合成到一起
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/Aa.jpg',1)
cv2.imshow('src',img)
(b,g,r) = cv2.split(img)#通道分解
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
result = cv2.merge((bH,gH,rH))# 通道合成
cv2.imshow('dst',result)
cv2.waitKey(0)
效果圖如下(左原圖,右均衡化圖片):
YUV圖像的直方圖均衡化
yuv是一種類似rgb的顏色模型,起源于黑白和彩電的過渡時期。
其中Y代表亮度,uv組合起來可以表示色度。
yuv信息只有y的信息就足以顯示黑白的圖片,
yuv和YCbCr表示相同的東西,且Cb嚴格對應U,Cr嚴格對應V
cv2.split(imgYUV)
圖像分解,將彩色圖片的RGB分解為R G B三個通道
cv2.equalizeHist(channelYUV[0])
對第一個顏色通道拿出來進行均衡化
cv2.merge(channelYUV)
將單一的顏色通道進行合成到一起
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/Aa.jpg',1)
imgYUV = cv2.cvtColor(img,cv2.COLOR_BGR2YCrCb)#將BGR彩色圖片轉換為YUV圖片
cv2.imshow('src',img)
channelYUV = cv2.split(imgYUV)
channelYUV[0] = cv2.equalizeHist(channelYUV[0])
channels = cv2.merge(channelYUV)
result = cv2.cvtColor(channels,cv2.COLOR_YCrCb2BGR)#將YUV圖片轉換為BGR彩色圖片
cv2.imshow('dst',result)
cv2.waitKey(0)
效果圖如下(左原圖,右均衡化圖片):
三、圖片修補
cv2.inpaint(img,paint,3,cv2.INPAINT_TELEA)
參數一:毀壞的圖片
參數二:修復的內容部分,mask模板
參數三:修復圖片的線條粗細值。由于毀壞圖片的時候進行的三個像素格的毀壞,故這里修復的線條粗細值為3
參數四:圖片修復類型
對一張圖片進行毀壞,并保存,這里使用的是改變圖片中某位置的像素值從而達到毀壞圖片的目的
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
for i in range(200,300):#對圖片進行畫線進行毀壞img[i,200] = (255,255,255)img[i,200+1] = (255,255,255)img[i,200-1] = (255,255,255)
for i in range(150,250):#對圖片進行畫線進行毀壞img[250,i] = (255,255,255)img[250+1,i] = (255,255,255)img[250-1,i] = (255,255,255)cv2.imwrite('E:\Jupyter_workspace\study\data/damaged.jpg',img)#保存一下毀壞的圖片
cv2.imshow('image',img)
cv2.waitKey(0)
效果圖如下:
對毀壞的圖片進行制作修復模板mask來修復圖片
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/damaged.jpg',1)#讀取毀壞的圖片信息
cv2.imshow('src',img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
paint = np.zeros((height,width,1),np.uint8)for i in range(200,300):#填補的模板參數,也就是剛才所繪制的畫線paint[i,200] = 255#為了使得線段更加paint[i,200+1] = 255paint[i,200-1] = 255
for i in range(150,250):paint[250,i] = 255paint[250+1,i] = 255paint[250-1,i] = 255
cv2.imshow('paint',paint)imgDst = cv2.inpaint(img,paint,3,cv2.INPAINT_TELEA)#定義目標圖片,即修復之后的圖片cv2.imshow('image',imgDst)
cv2.waitKey(0)
效果圖如下(左毀壞圖片,中修復模板mask掩模,右修復過后的圖片):
四、灰度直方圖源碼
灰度直方圖的本質:統計每個像素灰度值出現的概率0-255
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('E:\Jupyter_workspace\study/w1.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
count = np.zeros(256,np.float)
for i in range(0,height):for j in range(0,width):pixel = gray[i,j]index = int(pixel)count[index] = count[index]+1
for i in range(0,255):count[i] = count[i]/(height*width)
x = np.linspace(0,255,256)
y = count
plt.bar(x,y,0.9,alpha=1,color='r')
plt.show()
cv2.waitKey(0)
效果圖如下:
五、彩色直方圖源碼
彩色直方圖的本質:分別統計每個顏色通道上的像素值出現的概率0-255
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('E:\Jupyter_workspace\study/w1.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]#對每個顏色通道上的像素值進行統計
count_b = np.zeros(256,np.float)
count_g = np.zeros(256,np.float)
count_r = np.zeros(256,np.float)for i in range(0,height):for j in range(0,width):(b,g,r) = img[i,j]#圖片的像素值信息讀取到元組(b,g,r)中index_b = int(b)#將像素值轉換為int類型便于統計index_g = int(g)index_r = int(r)count_b[index_b] = count_b[index_b]+1#實現blue這個顏色通道上的像素的統計count_g[index_g] = count_g[index_g]+1count_r[index_r] = count_r[index_r]+1
for i in range(0,256):#遍歷每一個像素等級count_b[i] = count_b[i]/(height*width)#對像素值出現的個數進行歸一化處理count_g[i] = count_g[i]/(height*width)count_r[i] = count_r[i]/(height*width)
x = np.linspace(0,255,256)#從0開始,到255結束,一共256個
y1 = count_b
plt.figure()
plt.bar(x,y1,0.9,alpha=1,color='b')#繪制blue顏色通道的柱狀圖
y2 = count_g
plt.figure()
plt.bar(x,y2,0.9,alpha=1,color='g')
y3 = count_r
plt.figure()
plt.bar(x,y3,0.9,alpha=1,color='r')
plt.show()
cv2.waitKey(0)
效果圖如下:
六、灰度直方圖均衡化
本質:統計每個像素灰度 出現的概率 0-255
累計概率
灰度等級 | 出現的概率 | 累積概率 |
---|---|---|
1 | 0.2 | 0.1 |
2 | 0.3 | 0.5=0.2+0.3 |
3 | 0.1 | 0.6=0.2+0.3+0.1 |
總共256個灰度等級,每個灰度等級都會有一個出現概率,也都會有一個累積概率
灰度等級(100),累積概率(0.5),100到這個新值之間的映射(2550.5),以后所有的100等級這個像素都使用2550.5進行替代,替代完成之后就是直方圖的均衡化
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
#cv2.imshow('img',img)imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',gray)
count = np.zeros(256,np.float)
for i in range(0,height):for j in range(0,width):pixel = gray[i,j]index = int(pixel)count[index] = count[index]+1
for i in range(0,255):count[i] = count[i]/(height*width)
#計算累計概率
sum1 = float(0)
for i in range(0,256):sum1 = sum1+count[i]count[i] = sum1
#print(count)
# 計算映射表
map1 = np.zeros(256,np.uint16)
for i in range(0,256):map1[i] = np.uint16(count[i]*255)
# 映射
for i in range(0,height):for j in range(0,width):pixel = gray[i,j]gray[i,j] = map1[pixel]
cv2.imshow('dst',gray)
cv2.waitKey(0)
效果圖如下:
七、彩色直方圖均衡化
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
cv2.imshow('src',img)imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]count_b = np.zeros(256,np.float)
count_g = np.zeros(256,np.float)
count_r = np.zeros(256,np.float)
for i in range(0,height):for j in range(0,width):(b,g,r) = img[i,j]index_b = int(b)index_g = int(g)index_r = int(r)count_b[index_b] = count_b[index_b]+1count_g[index_g] = count_g[index_g]+1count_r[index_r] = count_r[index_r]+1
for i in range(0,255):count_b[i] = count_b[i]/(height*width)count_g[i] = count_g[i]/(height*width)count_r[i] = count_r[i]/(height*width)
#計算累計概率
sum_b = float(0)
sum_g = float(0)
sum_r = float(0)
for i in range(0,256):sum_b = sum_b+count_b[i]sum_g = sum_g+count_g[i]sum_r = sum_r+count_r[i]count_b[i] = sum_bcount_g[i] = sum_gcount_r[i] = sum_r
#print(count)
# 計算映射表
map_b = np.zeros(256,np.uint16)
map_g = np.zeros(256,np.uint16)
map_r = np.zeros(256,np.uint16)
for i in range(0,256):map_b[i] = np.uint16(count_b[i]*255)map_g[i] = np.uint16(count_g[i]*255)map_r[i] = np.uint16(count_r[i]*255)
# 映射
dst = np.zeros((height,width,3),np.uint8)
for i in range(0,height):for j in range(0,width):(b,g,r) = img[i,j]b = map_b[b]g = map_g[g]r = map_r[r]dst[i,j] = (b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果圖如下:
八、亮度增強
實現思路:在原來的亮度基礎上+40,從而達到亮度增強的效果
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src',img)
dst = np.zeros((height,width,3),np.uint8)
for i in range(0,height):for j in range(0,width):(b,g,r) = img[i,j]bb = int(b)+40gg = int(g)+40rr = int(r)+40if bb>255:bb = 255if gg>255:gg = 255if rr>255:rr = 255dst[i,j] = (bb,gg,rr)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果圖如下:
當然也可以改變顏色通道乘以一個比例系數再加上一個常數的方法實現美白效果
例如:(b1.3)+10、(g1.2)+15、r不變
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src',img)
dst = np.zeros((height,width,3),np.uint8)
for i in range(0,height):for j in range(0,width):(b,g,r) = img[i,j]bb = int(b*1.3)+10gg = int(g*1.2)+15if bb>255:bb = 255if gg>255:gg = 255dst[i,j] = (bb,gg,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果圖如下:
九、磨皮美白
調用API雙邊濾波
雙邊濾波:高斯濾波核g+距離核r,進行加權算出一個共同的核p,并用當前的和乘以像素,與像素進行卷積,就可以得到一個新的像素,這個新的像素就是經過雙邊濾波后的像素
import cv2
img = cv2.imread('E:\Jupyter_workspace\study\data/test1.png',1)
cv2.imshow('src',img)
dst = cv2.bilateralFilter(img,15,35,35)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果圖如下:
十、高斯、均值濾波
濾波0的本質:矩陣對應點相乘并求和
右邊是卷積核,為啥成1/16,是因為這個卷積元素之和為16,而且這個卷積核越中間值越大,越兩邊值越小
高斯濾波使用API的方式進行調用
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/test1.png',1)
cv2.imshow('src',img)
dst = cv2.GaussianBlur(img,(5,5),1.5)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果圖如下:
均值濾波使用源碼方式進行調用(為了防止溢出,圖像邊緣并進行處理)
首先定義一個模板,比如66的模板,數據全為1,用這個全為1的模板數據 乘以 一個66矩陣中的所有的數據,乘完之后再除以36,這樣便得到一個均值,把這個均值替換掉原來的像素值,則實現均值濾波效果
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/test1.png',1)
cv2.imshow('src',img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)
for i in range(3,height-3):for j in range(3,width-3):sum_b = int(0)sum_g = int(0)sum_r = int(0)for m in range(-3,3):#-3 -2 -1 0 1 2for n in range(-3,3):(b,g,r) = img[i+m,j+n]sum_b = sum_b+int(b)sum_g = sum_g+int(g)sum_r = sum_r+int(r)b = np.uint8(sum_b/36)g = np.uint8(sum_g/36)r = np.uint8(sum_r/36)dst[i,j] = (b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果圖如下:
十一、中值濾波
算法思路:假如定義一個3*3的模板,這個模板中一共有9個像素,將這9個像素進行排序,排序之后選擇中間的那個像素值去代替其他像素值
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/test1.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
cv2.imshow('src',img)
dst = np.zeros((height,width,3),np.uint8)
collect = np.zeros(9,np.uint8)
for i in range(1,height-1):for j in range(1,width-1):k = 0for m in range(-1,2):#-1 0 1for n in range(-1,2):gray = img[i+m,j+n]collect[k] = grayk = k+1for k in range(0,9):#冒泡排序,從前往后比較,每輪比較選出最大值放到最后面p1 = collect[k]for t in range(k+1,9):if p1<collect[t]:mid = collect[t]collect[t] = p1p1 = middst[i,j] = collect[4]#該值就是中間值,用中間值去代替所有的像素值
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果圖如下: