计算机视觉之图像美化(实现图片直方图、直方图均衡化、图片修补、亮度增强、磨皮美白、高斯均值滤波、中值滤波等功能)
1.彩色图片直方图
测试代码如下:
1 import cv2 2 import numpy as np 3 def ImageHist(image,type): 4 color = (255,255,255) 5 windowName = 'Gray' 6 if type == 31: 7 color = (255,0,0) 8 windowName = 'B Hist' 9 elif type == 32: 10 color = (0,255,0) 11 windowName = 'G Hist' 12 elif type == 33: 13 color = (0,0,255) 14 windowName = 'R Hist' 15 # 参数 1 image 2 第一个通道 3模板 4 分成多少份 5各像素的值 16 hist = cv2.calcHist([image],[0],None,[256],[0.0,255.0]) 17 minV,maxV,minL,maxL = cv2.minMaxLoc(hist) 18 histImg = np.zeros([256,256,3],np.uint8) 19 for h in range(256): 20 intenNormal = int(hist[h]*256/maxV) 21 cv2.line(histImg,(h,256),(h,256-intenNormal),color) 22 cv2.imshow(windowName,histImg) 23 return histImg 24 img = cv2.imread('image0.jpg', 1) 25 channels = cv2.split(img) # 分解成三个通道 26 print(channels) 27 for i in range(0,3): 28 ImageHist(channels[i],31+i) 29 cv2.waitKey(0)
运行结果如下:
蓝色通道下的直方图:
绿色通道下的直方图:
红色通道下的直方图:
灰度直方图源码实现:
1 # encoding:utf-8 2 3 import cv2 4 import numpy as np 5 import matplotlib.pyplot as plt 6 7 # 本质 统计每个像素灰度 出现的概率 0-255 p 8 img = cv2.imread('image0.jpg',1) 9 imgInfo = img.shape 10 height = imgInfo[0] 11 width = imgInfo[1] 12 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 13 cnt = np.zeros(256,np.float) 14 for i in range(0,height): 15 for j in range(0,width): 16 pixel = gray[i,j] 17 index = int(pixel) 18 cnt[index] = cnt[index]+1 19 for i in range(0,256): 20 cnt[i] = cnt[i]/(height*width) 21 # x轴 22 x = np.linspace(0,255,256) 23 # y轴 24 y = cnt 25 plt.bar(x,y,0.9,alpha=1,color='b') 26 plt.show() 27 cv2.waitKey(0)
运行结果如下:
彩色直方图源码实现:
1 # encoding:utf-8 2 3 import cv2 4 import numpy as np 5 import matplotlib.pyplot as plt 6 7 # 本质 统计每个像素灰度 出现的概率 0-255 p 8 img = cv2.imread('image0.jpg',1) 9 imgInfo = img.shape 10 height = imgInfo[0] 11 width = imgInfo[1] 12 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 13 cnt_b = np.zeros(256,np.float) 14 cnt_g = np.zeros(256,np.float) 15 cnt_r = np.zeros(256,np.float) 16 for i in range(0,height): 17 for j in range(0,width): 18 (b,g,r) = img[i,j] 19 index_b = int(b) 20 index_g = int(g) 21 index_r = int(r) 22 cnt_b[index_b] = cnt_b[index_b]+1 23 cnt_r[index_r] = cnt_r[index_r]+1 24 cnt_g[index_g] = cnt_g[index_g]+1 25 for i in range(0,256): 26 cnt_b[i] = cnt_b[i]/(height*width) 27 cnt_r[i] = cnt_r[i]/(height*width) 28 cnt_r[i] = cnt_r[i]/(height*width) 29 # x轴 30 x = np.linspace(0,255,256) 31 # y轴 32 y_b = cnt_b 33 plt.figure() 34 plt.bar(x,y_b,0.9,alpha=1,color='b') 35 y_r = cnt_r 36 plt.figure() 37 plt.bar(x,y_r,0.9,alpha=1,color='r') 38 y_g = cnt_g 39 plt.figure() 40 plt.bar(x,y_g,0.9,alpha=1,color='g') 41 plt.show() 42 cv2.waitKey(0)
蓝色通道下:
绿色通道下:
红色通道下:
2.直方图均衡化
灰度图均衡化:
测试代码如下:
1 import cv2 2 import numpy as np 3 img = cv2.imread('image0.jpg', 1) 4 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 5 cv2.imshow('src',gray) 6 dst = cv2.equalizeHist(gray) 7 cv2.imshow('dst',dst) 8 cv2.waitKey(0)
运行结果如下:
src初始图像:
均衡化后的图像:
BGR彩色图均衡化:
测试代码如下:
1 import cv2 2 import numpy as np 3 img = cv2.imread('image0.jpg', 1) 4 cv2.imshow('src',img) 5 # 通道分解分割成三个分量 6 (b,g,r) = cv2.split(img) 7 bH = cv2.equalizeHist(b) 8 gH = cv2.equalizeHist(g) 9 rH = cv2.equalizeHist(r) 10 # 通道合成 11 result = cv2.merge((bH,gH,rH)) 12 cv2.imshow('dst',result) 13 cv2.waitKey(0)
运行结果如下:
src为初始图像:
dst为均衡化之后的图像:
其他的均衡化:(待补充。。。)
测试代码如下:
1 import cv2 2 import numpy as np 3 img = cv2.imread('image0.jpg', 1) 4 imgYUV = cv2.cvtColor(img,cv2.COLOR_BGR2YCrCb) 5 cv2.imshow('src',img) 6 channelYUV = cv2.split(imgYUV) 7 # for i in range(0,3): 8 # channelYUV[i] = cv2.equalizeHist(channelYUV[i]) 9 # channelYUV[0] = cv2.equalizeHist(channelYUV[0]) 10 channelYUV[1] = cv2.equalizeHist(channelYUV[1]) 11 # channelYUV[2] = cv2.equalizeHist(channelYUV[2]) 12 channels = cv2.merge(channelYUV) 13 result = cv2.cvtColor(channels,cv2.COLOR_YCrCb2BGR) 14 cv2.imshow('dst',result) 15 cv2.waitKey(0)
运行结果如下:
src原图像:
绿色通道下:
红色通道下:
蓝色通道下:
三个通道一起:
灰度直方图均衡化源码实现:
1 # 本质 统计每个像素灰度 出现的概率 0-255 p 2 # 累积概率 3 # 1 0.2 0.2 4 # 2 0.3 0.5 5 # 3 0.1 0.6 6 # 256个累积概率 7 import cv2 8 import numpy as np 9 import matplotlib.pyplot as plt 10 img = cv2.imread('image0.jpg',1) 11 imgInfo = img.shape 12 height = imgInfo[0] 13 width = imgInfo[1] 14 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 15 cv2.imshow('src',gray) 16 count = np.zeros(256,np.float) 17 for i in range(0,height): 18 for j in range(0,width): 19 pixel = gray[i,j] 20 index = int(pixel) 21 count[index] = count[index]+1 22 for i in range(0,255): 23 count[i] = count[i]/(height*width) 24 # 计算累计概率 25 sum1 = float(0) 26 for i in range(0,256): 27 sum1 = sum1+count[i] 28 count[i] = sum1 29 # print(count) 30 # 计算映射表 31 map1 = np.zeros(256,np.uint16) 32 for i in range(0,256): 33 map1[i] = np.uint16(count[i]*255) 34 # 映射 35 for i in range(0,height): 36 for j in range(0,width): 37 pixel = gray[i,j] 38 gray[i,j] = map1[pixel] 39 cv2.imshow('dst',gray) 40 cv2.waitKey(0)
运行结果:
彩色直方图均衡化源码实现:
1 # encoding:utf-8 2 3 import cv2 4 import numpy as np 5 import matplotlib.pyplot as plt 6 7 # 本质 统计每个像素灰度 出现的概率 0-255 p 8 img = cv2.imread('image0.jpg',1) 9 cv2.imshow('src',img) 10 imgInfo = img.shape 11 height = imgInfo[0] 12 width = imgInfo[1] 13 # gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 14 cnt_b = np.zeros(256,np.float) 15 cnt_g = np.zeros(256,np.float) 16 cnt_r = np.zeros(256,np.float) 17 for i in range(0,height): 18 for j in range(0,width): 19 (b,g,r) = img[i,j] 20 index_b = int(b) 21 index_g = int(g) 22 index_r = int(r) 23 cnt_b[index_b] = cnt_b[index_b]+1 24 cnt_r[index_r] = cnt_r[index_r]+1 25 cnt_g[index_g] = cnt_g[index_g]+1 26 for i in range(0,256): 27 cnt_b[i] = cnt_b[i]/(height*width) 28 cnt_r[i] = cnt_r[i]/(height*width) 29 cnt_g[i] = cnt_g[i]/(height*width) 30 # 计算机累积概率 31 sum_b = float(0) 32 sum_g = float(0) 33 sum_r = float(0) 34 for i in range(0,256): 35 sum_b = sum_b+cnt_b[i] 36 sum_g = sum_g+cnt_g[i] 37 sum_r = sum_r+cnt_r[i] 38 cnt_b[i] = sum_b 39 cnt_g[i] = sum_g 40 cnt_r[i] = sum_r 41 # 生成映射表 42 map_b = np.zeros(256,np.uint16) 43 map_g = np.zeros(256,np.uint16) 44 map_r = np.zeros(256,np.uint16) 45 for i in range(0,256): 46 map_b[i] = np.uint16(cnt_b[i]*255) 47 map_g[i] = np.uint16(cnt_g[i]*255) 48 map_r[i] = np.uint16(cnt_r[i]*255) 49 # 映射 50 dst = np.zeros((height,width,3),np.uint8) 51 for i in range(0,height): 52 for j in range(0,width): 53 (n,g,r) = img[i,j] 54 b = map_b[b] 55 g = map_g[g] 56 r = map_r[r] 57 dst[i,j]= (b,g,r) 58 cv2.imshow('dst',dst) 59 cv2.waitKey(0)
运行结果:
3.图片修补
首先构建一副画图:
1 import cv2 2 import numpy as np 3 4 img = cv2.imread('image0.jpg',1) 5 for i in range(200,300): 6 img[i,200] = (255,255,255) 7 img[i,200+1] = (255,255,255) 8 img[i,200-1] = (255,255,255) 9 for i in range(150,250): 10 img[250,i] = (255,255,255) 11 img[250+1,i] = (255,255,255) 12 img[250-1,i] = (255,255,255) 13 cv2.imwrite('damaged.jpg',img) 14 cv2.imshow('damaged.jpg',img) 15 cv2.waitKey(0)
构建的坏图为:(多了一个白十字)
修补坏图,测试代码如下:
1 # 1 坏图 2 修补那一部分 3 调用api实现修补 2 import cv2 3 import numpy as np 4 img = cv2.imread('damaged.jpg',1) 5 cv2.imshow('damaged',img) 6 imgInfo = img.shape 7 height = imgInfo[0] 8 width = imgInfo[1] 9 paint = np.zeros((height,width,1),np.uint8) 10 for i in range(200,300): 11 paint[i,200] = 255 12 paint[i,200+1] = 255 13 paint[i,200-1] = 255 14 for i in range(150,250): 15 paint[250,i] = 255 16 paint[250+1,i] = 255 17 paint[250-1,i] = 255 18 cv2.imshow('paint',paint) 19 # 完成图片修补 1 src 2 mask 20 imgDst = cv2.inpaint(img,paint,3,cv2.INPAINT_TELEA) 21 cv2.imshow('image',imgDst) 22 cv2.waitKey(0)
画图的特征图:(即需要修补的部分)
修补后的图像:
修补成功!
4.亮度增强
测试代码如下:
1 # encoding:utf-8 2 import cv2 3 import numpy as np 4 img = cv2.imread('image0.jpg',1) 5 imgInfo = img.shape 6 height = imgInfo[0] 7 width = imgInfo[1] 8 cv2.imshow('src',img) 9 dst = np.zeros((height,width,3),np.uint8) 10 for i in range(0,height): 11 for j in range(0,width): 12 (b,g,r) = img[i,j] 13 bb = int(b)+40 14 rr = int(r)+40 15 gg = int(g)+40 16 if bb>255: 17 bb = 255 18 if rr>255: 19 rr = 255 20 if gg>255: 21 gg = 255 22 dst[i,j] = (bb,gg,rr) 23 cv2.imshow('dst',dst) 24 cv2.waitKey(0)
运行结果如下:
src为原图像:
dst为亮度增强后的图像:
另一种方式实现亮度增强,测试代码如下:
1 import cv2 2 import numpy as np 3 img = cv2.imread('image0.jpg',1) 4 imgInfo = img.shape 5 height = imgInfo[0] 6 width = imgInfo[1] 7 cv2.imshow('src',img) 8 dst = np.zeros((height,width,3),np.uint8) 9 for i in range(0,height): 10 for j in range(0,width): 11 (b,g,r) = img[i,j] 12 bb = int(b*1.3)+10 13 gg = int(g*1.2)+15 14 if bb>255: 15 bb = 255 16 if gg>255: 17 gg = 255 18 dst[i,j] = (bb,gg,r) 19 cv2.imshow('dst',dst) 20 cv2.waitKey(0)
亮度增强后的图像为:
5.磨皮美白
测试代码如下:
1 # 双边滤波 磨皮美白 2 import cv2 3 import numpy as np 4 img = cv2.imread('1.jpg',1) 5 cv2.imshow('src',img) 6 imgInfo = img.shape 7 height = imgInfo[0] 8 width = imgInfo[1] 9 dst = cv2.bilateralFilter(img,15,35,35) 10 cv2.imshow('dst',dst) 11 cv2.waitKey(0)
测试结果如下:
src为原图像:
dst为处理后的图像:
6.高斯均值滤波
调用api实现, 测试代码如下:
1 import cv2 2 import numpy as np 3 img = cv2.imread('image11.jpg',1) # 含有椒盐噪声的发发 4 cv2.imshow('src',img) 5 dst = cv2.GaussianBlur(img,(5,5),1.5) 6 cv2.imshow('dst',dst) 7 cv2.waitKey(0)
运行结果如下:
src为添加了噪声的图像:
dst为高斯均值滤波后的图像:
自己实现均值滤波,测试代码如下:
1 # 均值 模板6*6 用模板6*6求得的均值替代中心值 2 import cv2 3 import numpy as np 4 img = cv2.imread('image11.jpg',1) # 含有椒盐噪声的发发 5 cv2.imshow('src',img) 6 imgInfo = img.shape 7 height = imgInfo[0] 8 width = imgInfo[1] 9 dst = np.zeros((height,width,3),np.uint8) 10 b = np.zeros(1,np.uint8) 11 g = np.zeros(1,np.uint8) 12 r = np.zeros(1,np.uint8) 13 for i in range(3,height-3): 14 for j in range(3,width-3): 15 sum_b = int(0) 16 sum_g = int(0) 17 sum_r = int(0) 18 for m in range(-3,3): 19 for n in range(-3,3): 20 (b,g,r) = img[i+m,j+n] 21 sum_b = sum_b+int(b) 22 sum_g = sum_g+int(g) 23 sum_r = sum_r+int(r) 24 b = np.uint8(sum_b/36) 25 g = np.uint8(sum_g/36) 26 r = np.uint8(sum_r/36) 27 dst[i,j] = (b,g,r) 28 cv2.imshow('dst',dst) 29 cv2.waitKey(0)
运行结果如下:(处理后的图像)
7.中值滤波
测试代码如下:
1 # 中值滤波 用模板6*6求得的中值替代中心值 2 import cv2 3 import numpy as np 4 img = cv2.imread('image11.jpg',1) # 含有椒盐噪声的发发 5 imgInfo = img.shape 6 height = imgInfo[0] 7 width = imgInfo[1] 8 img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 9 cv2.imshow('src',img) 10 dst = np.zeros((height,width,3),np.uint8) 11 collect = np.zeros(9,np.uint8) 12 for i in range(1,height-2): 13 for j in range(1,width-2): 14 k = 0 15 for m in range(-1,2): 16 for n in range(-1,2): 17 gray = img[i+m,j+n] 18 collect[k] = gray 19 k = k+1 20 # 排序 21 for k in range(0,9): 22 p1 = collect[k] 23 for t in range(k+1,9): 24 if p1<collect[t]: 25 mid = collect[t] 26 collect[t] = p1 27 p1 = mid 28 dst[i,j] = collect[4] 29 cv2.imshow('dst',dst) 30 cv2.waitKey(0)
运行结果如下:
src初始图像:
dst处理后的图像: