接着上一篇图像处理那点事儿之凌波微步,我们今天来谈谈化妆术。你要了解颜色搭配,风格转换,提高你的审美,要不然女神会觉得被你喜欢是一件很丢人的事情。
2.图像美化
1.直方图
直方图可以很好的展示出图片中各种颜色分布的比重,对于我们分析图片有很大的帮助。实现起来也是很简单的,我们只需要把每种颜色值出现的比率计算出来,使用plt展示即可;有一点需要注意,颜色的计算需要分通道进行。
#原理,把0-255每个颜色所占像素点的数量用线段表示出来,不同的线段长度表示不用颜色的分布情况
#使用opencv绘制彩色图像直方图
#1.定义窗口名称 2.计算直方图信息 3.绘制直方图
import cv2
import numpy as np
#直方图计算逻辑
def imageHist(image,type):
color = (255,255,255)
#1.定义显示窗口的名称 只有窗口名称不一致才可以同时展示多张图像
windowName = 'Gray'
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'
#计算直方图信息
# image channels mask histsize range
hist = cv2.calcHist([image],[0],None,[256],[0.0,255.0])
#计算数组的最大最小值
minV,maxV,minL,maxL = cv2.minMaxLoc(hist)
print(maxV)
#定义要展示的hist图像
histImg = np.zeros([256,256,3],np.uint8)
#3.绘制直方图信息
for i in range(256):
intenNormal =int(hist[i]*256/maxV)
cv2.line(histImg,(i,256),(i,256-intenNormal),color)
cv2.imshow(windowName,histImg)
return histImg
#遍历图像通道,调用方法
img =cv2.imread('images/jinzhiyuan.jpg',1)
#将图像按照通道进行分解RGB
channels = cv2.split(img);
for i in range(0,3):
imageHist(channels[i],i+31)
cv2.waitKey(0)
#灰色直方图源码
#原理 求出各种颜色值所占比例大小,进行绘制
import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('images/blue.jpg',0)
imginfo = img.shape
height = imginfo[0]
width = imginfo[1]
count = np.zeros(256,np.float)
for i in range(height):
for j in range(width):
colorV = img[i,j]
count[colorV] = count[colorV]+1
for c in range(0,255):
count[c] = count[c]/(height*width)
x = np.linspace(0,255,256)
y = count
plt.bar(x,y,0.9,color='b')
plt.show()
#彩色直方图源码
#原理 在灰度直方图的基础上,在rgb三个维度上进行统计 求出各种颜色值所占比例大小,进行绘制
import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('images/tangwei.jpg',1)
imginfo = img.shape
height = imginfo[0]
width = imginfo[1]
countb = np.zeros(256,np.float)
countg = np.zeros(256,np.float)
countr = np.zeros(256,np.float)
for i in range(height):
for j in range(width):
(b,g,r) = img[i,j]
countb[b] = count[b]+1
countg[g] = count[g]+1
countr[r] = count[r]+1
for c in range(0,255):
countb[c] = countb[c]/(height*width)
countg[c] = countg[c]/(height*width)
countr[c] = countr[c]/(height*width)
x = np.linspace(0,255,256)
yb = countb
plt.figure()
plt.bar(x,yb,0.9,color='b')
yg = countg
plt.figure()
plt.bar(x,yg,0.9,color='g')
yr = countr
plt.figure()
plt.bar(x,yr,0.9,color='r')
plt.show()
2.图片修补
女神的照片上有一块缺失了怎么办?好着急啊。放心交给我吧,有我在你什么都不怕。图片修补是制作 一个只包含缺失块的图像蒙版,然后 调用cv2.inpaint,这个方法会对原图中蒙版的部分进行修补,修补的方式是采用半径为n的周围点的像素计算。
#1.对图像进行破坏
import cv2
import numpy as np
img = cv2.imread('images/tongliya.jpg',1)
for i in range(200,300):
img[250,i] = (255,255,255)
img[250+1,i] = (255,255,255)
img[250-1,i] = (255,255,255)
for j in range(200,300):
img[j,250] = (255,255,255)
img[j,250-1] = (255,255,255)
img[j,250+1] = (255,255,255)
cv2.imshow('img',img)
cv2.imwrite('images/damage.jpg',img)
cv2.waitKey(0)
#图片修补
#1.利用缺失的位置生成修补图片
#2.调用cv2.inpaint进行修补
import cv2
import numpy as np
img = cv2.imread('images/damage.jpg',1)
img_info = img.shape
height = img_info[0]
width = img_info[1]
mask_img = np.zeros([height,width,1],np.uint8)
for i in range(200,300):
mask_img[250,i] = 111
mask_img[250+1,i] = 111
mask_img[250-1,i] = 255
for j in range(200,300):
mask_img[j,250] = 1
mask_img[j,250-1] = 255
mask_img[j,250+1] = 255
#INPAINT_TELEA
#修补的原理是
#mask_img 中不为0的区域作为img中待修补区域,3表示使用点附近半径为3的像素计算点的像素
result = cv2.inpaint(img,mask_img,3,cv2.INPAINT_NS)
cv2.imshow('img',img)
cv2.imshow('mask_img',mask_img)
cv2.imshow('result',result)
cv2.waitKey(0)
###3. 均衡化
均衡化可以调整图像的对比度,对比度就是图片中最亮的白色到最暗的黑之间不同层级的测量。效果跟亮度的调整类似,但是和直接调整亮度不同的是,对比度调整是把亮度分成了很多层分别进行调整,调整后的效果是更深、更亮
#彩色图像均衡化 1.分通道 2.均衡化各通道 3合并
import cv2
import numpy as np
img = cv2.imread('images/liqin.jpg',1)
cv2.imshow('img',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('hist',result)
cv2.waitKey(0)
#彩色直方图均衡化源码
#原理:就是在灰度均衡化基础上增加2个通道的处理
#将不同层级的亮度分布,践行整体调整
#步骤 1.计算累计概率 2.定义映射表 3.进行映射
import numpy as np
import cv2
img = cv2.imread('images/tangwei.jpg',1)
cv2.imshow('img',img)
imginfo = img.shape
height = imginfo[0]
width = imginfo[1]
countb = np.zeros(256,np.float)
countg = np.zeros(256,np.float)
countr = np.zeros(256,np.float)
for i in range(height):
for j in range(width):
(b,g,r) = img[i,j]
countb[b] = countb[b]+1
countg[g] = countg[g]+1
countr[r] = countr[r]+1
for c in range(0,256):
countb[c] = countb[c]/(height*width)
countg[c] = countg[c]/(height*width)
countr[c] = countr[c]/(height*width)
#1.计算累计概率
sumb = float(0)
sumg = float(0)
sumr = float(0)
for i in range(0,256):
sumb = sumb+countb[i]
countb[i] = sumb
sumg = sumg+countg[i]
countg[i] = sumg
sumr = sumr+countr[i]
countr[i] = sumr
#2. 定义映射表 映射关系为 x*255
mapb = np.zeros(256,np.uint16)
mapg = np.zeros(256,np.uint16)
mapr = np.zeros(256,np.uint16)
for i in range(0,256):
mapb[i] = countb[i]*255
mapg[i] = countg[i]*255
mapr[i] = countr[i]*255
for i in range(height):
for j in range(width):
(b,g,r) = img[i,j]
b = mapb[b]
g = mapg[g]
r = mapr[r]
img[i,j] = (b,g,r)
cv2.imshow('dest',img)
cv2.waitKey(0)
4.亮度增强
要让一个人变靚比登天还难,要让一张图变亮比睡觉还简单。把每一个像素值都变大就好了。
#亮度增强
#原理:将每种颜色的值增大
#跟对比度的区别是 对比度均衡化是按照比例,使黑的更黑,白的更白
import cv2
import numpy as np
img = cv2.imread('images/tangwei.jpg',1)
cv2.imshow('img',img)
img_info = img.shape
height = img_info[0]
width = img_info[1]
for i in range(0,height):
for j in range(0,width):
(b,g,r) = img[i,j]
b_new = min(b*1.5+50,255)
g_new = min(g*1.5+50,255)
r_new = min(r*1.5+50,255)
img[i,j] = (b_new,g_new,r_new)
cv2.imshow('dest',img)
cv2.waitKey(0)
5.磨皮美白
磨皮美白会去掉原来图片中的噪声点,使照片看起来更干净、美好
#磨皮美白
#使用双边滤波进行美白
import cv2
import numpy as np
img = cv2.imread('images/liuhui2.jpg',1)
cv2.imshow('img',img)
#双边滤波
dest = cv2.bilateralFilter(img,15,35,35)
cv2.imshow('dest',dest)
cv2.waitKey(0)
6.滤波器
高斯滤波、均值滤波、中值滤波都是取出图像噪声点的方式。不过方式略有不同,均值滤波使用一个n*n的滤波器点乘图像中的区域,使用点乘后的均值作为当前像素点的值。中值滤波也是点乘,使用点乘后的中位数作为当前像素点的值;高斯滤波的滤波器中每一个点的权重是不一样的,离目标点越近的点拥有越高的权值,然后进行加权平均
#高斯滤波
import cv2
import numpy as np
img = cv2.imread('images/tangwei.jpg',1)
cv2.imshow('img',img)
#高斯滤波
dest = cv2.GaussianBlur(img,(5,5),1.5)
cv2.imwrite('images/gaussian.jpg',dest)
cv2.imshow('dest',dest)
cv2.waitKey(0)
#均值滤波
#原理 在n*n的区域内求均值,作为当前的值 相当于平均池化
#步骤 相当于把每个点和它后面、下面的n个点加起来,求平均值作为这个点的值
#对于每行每列最后n个值暂时没有进行处理
import cv2
import numpy as np
img = cv2.imread('images/tangwei.jpg',1)
cv2.imshow('img',img)
img_info = img.shape
height = img_info[0]
width = img_info[1]
#dest = np.zeros([height,width,3],np.uint8)
for i in range(0,height-6):
for j in range(0,width-6):
sumb = int(0)
sumg = int(0)
sumr = int(0)
for h in range(0,6):
for w in range(0,6):
(b,g,r) = img[i+h,j+w]
sumb+=int(b)
sumg+=int(g)
sumr+=int(r)
img[i,j] = (sumb/36,sumg/36,sumr/36)
cv2.imshow('dest',img)
cv2.waitKey(0)
#中值滤波
#原理 在n*n的区域内求中间值,作为当前的值
import cv2
import numpy as np
img = cv2.imread('images/liqin.jpg',1)
cv2.imshow('img',img)
img_info = img.shape
height = img_info[0]
width = img_info[1]
#dest = np.zeros([height,width,3],np.uint8)
collectb = np.zeros(9,np.uint8)
collectg = np.zeros(9,np.uint8)
collectr = np.zeros(9,np.uint8)
for i in range(0,height-3):
for j in range(0,width-3):
k = 0;
for h in range(0,3):
for w in range(0,3):
(b,g,r) = img[i+h,j+w]
collectb[k] = b
collectg[k] = g
collectr[k] = r
k+=1
#冒泡排序
for l in range(0,9):
bl = collectb[l]
gl = collectg[l]
rl = collectr[l]
for r in range(l+1,9):
if(bl<collectb[r]):
collectb[l] = collectb[r]
collectb[r] = bl
if(gl<collectg[r]):
collectg[l] = collectg[r]
collectg[r] = gl
if(rl<collectr[r]):
collectr[l] = collectr[r]
collectr[r] = rl
b_middle = collectb[4]
g_middle = collectg[4]
r_middle = collectr[4]
img[i,j] = (b_middle,g_middle,r_middle)
cv2.imshow('dest',img)
cv2.waitKey(0)
图像美化章节且告一段落
是我勇敢太久,决定为你一个人而活
不能说出口那么折磨,勇敢了太久城市充满短暂的烟火
无处躲,照亮了沉默
明白是寂寞《勇敢-张惠妹》
如果喜欢,请继续观看下一篇《图像处理那点事儿之三特异功能》