基于OpenCV的计算机视觉入门(5)图像美化(下)
灰度直方图均衡化
一是为什么要选用累积分布函数,二是为什么使用累积分布函数处理后像素值会均匀分布。
第一个问题。均衡化过程中,必须要保证两个条件:
①像素无论怎么映射,一定要保证原来的大小关系不变,较亮的区域,依旧是较亮的,较暗依旧暗,只是对比度增大,绝对不能明暗颠倒;
②如果是八位图像,那么像素映射函数的值域应在0和255之间的,不能越界。
综合以上两个条件,累积分布函数是个好的选择,因为累积分布函数是单调增函数(控制大小关系),并且值域是0到1(控制越界问题),所以直方图均衡化中使用的是累积分布函数。
第二个问题。累积分布函数具有一些好的性质,那么如何运用累积分布函数使得直方图均衡化?比较概率分布函数和累积分布函数,前者的二维图像是参差不齐的,后者是单调递增的。直方图均衡化过程中,映射方法是
n是图像中像素的总和,nk是当前灰度级的像素个数,L是图像中可能的灰度级总数。
假设有如下图像:
统计并映射
图像显示为
python 实现
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('images/03.jpeg',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)
#计算累计概率
sum1 =float(0)
for i in range(0,256):
sum1 = sum1+count[i]
count[i] = sum1
print(count)
输出结果:
[3.73333333e-05 1.70666667e-04 3.41333333e-04 3.89333333e-04
4.69333333e-04 5.33333333e-04 5.54666667e-04 5.86666667e-04
6.45333333e-04 7.09333333e-04 7.62666667e-04 8.32000000e-04
9.17333333e-04 1.01866667e-03 1.06666667e-03 1.15200000e-03
1.26400000e-03 1.39733333e-03 1.56266667e-03 1.75466667e-03
2.06933333e-03 2.45866667e-03 3.13066667e-03 4.67733333e-03
7.14666667e-03 1.05973333e-02 1.53600000e-02 2.01120000e-02
2.48640000e-02 2.92853333e-02 3.35413333e-02 3.77333333e-02
4.12160000e-02 4.44533333e-02 4.77760000e-02 5.08000000e-02
5.42453333e-02 5.68906667e-02 5.88800000e-02 6.10453333e-02
6.39893333e-02 6.63146667e-02 6.83040000e-02 7.04426667e-02
7.27253333e-02 7.51946667e-02 7.78506667e-02 8.02293333e-02
8.21920000e-02 8.40586667e-02 8.59893333e-02 8.82560000e-02
9.04213333e-02 9.28266667e-02 9.50773333e-02 9.73866667e-02
9.94186667e-02 1.01632000e-01 1.03605333e-01 1.05349333e-01
1.07237333e-01 1.09200000e-01 1.10965333e-01 1.13317333e-01
1.15552000e-01 1.17760000e-01 1.19824000e-01 1.21760000e-01
1.24085333e-01 1.26256000e-01 1.28608000e-01 1.30896000e-01
1.33168000e-01 1.35573333e-01 1.37808000e-01 1.40085333e-01
1.42304000e-01 1.44528000e-01 1.46720000e-01 1.48784000e-01
1.50762667e-01 1.53040000e-01 1.54997333e-01 1.57141333e-01
1.59088000e-01 1.61136000e-01 1.63018667e-01 1.64928000e-01
1.66832000e-01 1.68928000e-01 1.70794667e-01 1.72677333e-01
1.74592000e-01 1.76485333e-01 1.78640000e-01 1.80592000e-01
1.82842667e-01 1.84970667e-01 1.87173333e-01 1.89280000e-01
1.91402667e-01 1.93840000e-01 1.96181333e-01 1.98810667e-01
2.01557333e-01 2.04554667e-01 2.07264000e-01 2.10010667e-01
2.12954667e-01 2.15984000e-01 2.18906667e-01 2.21610667e-01
2.24640000e-01 2.27642667e-01 2.30741333e-01 2.33616000e-01
2.36661333e-01 2.39594667e-01 2.42608000e-01 2.45877333e-01
2.49008000e-01 2.52208000e-01 2.55578667e-01 2.58880000e-01
2.62464000e-01 2.65946667e-01 2.69264000e-01 2.72586667e-01
2.76042667e-01 2.79392000e-01 2.82442667e-01 2.85781333e-01
2.89013333e-01 2.92304000e-01 2.95477333e-01 2.98362667e-01
3.01077333e-01 3.04074667e-01 3.07088000e-01 3.10213333e-01
3.13274667e-01 3.16394667e-01 3.19402667e-01 3.22405333e-01
3.25413333e-01 3.28666667e-01 3.31642667e-01 3.34570667e-01
3.38069333e-01 3.41354667e-01 3.44853333e-01 3.48400000e-01
3.52122667e-01 3.55749333e-01 3.59584000e-01 3.63717333e-01
3.67914667e-01 3.72224000e-01 3.76544000e-01 3.80954667e-01
3.85120000e-01 3.89493333e-01 3.94181333e-01 3.98938667e-01
4.03866667e-01 4.09077333e-01 4.13845333e-01 4.18832000e-01
4.24384000e-01 4.29530667e-01 4.34613333e-01 4.39776000e-01
4.44560000e-01 4.49504000e-01 4.54421333e-01 4.59168000e-01
4.63845333e-01 4.68725333e-01 4.73434667e-01 4.77936000e-01
4.82240000e-01 4.86597333e-01 4.90880000e-01 4.95573333e-01
4.99861333e-01 5.04528000e-01 5.09296000e-01 5.14053333e-01
5.18192000e-01 5.22853333e-01 5.26741333e-01 5.30624000e-01
5.34352000e-01 5.38101333e-01 5.42176000e-01 5.46325333e-01
5.50106667e-01 5.53962667e-01 5.57728000e-01 5.61760000e-01
5.65125333e-01 5.68805333e-01 5.72656000e-01 5.76821333e-01
5.80746667e-01 5.85221333e-01 5.89194667e-01 5.93717333e-01
5.98261333e-01 6.02944000e-01 6.07221333e-01 6.12154667e-01
6.16906667e-01 6.21845333e-01 6.27322667e-01 6.32405333e-01
6.37989333e-01 6.43536000e-01 6.48938667e-01 6.54528000e-01
6.59877333e-01 6.64912000e-01 6.69205333e-01 6.73749333e-01
6.78474667e-01 6.83146667e-01 6.87472000e-01 6.91936000e-01
6.95626667e-01 6.99280000e-01 7.02736000e-01 7.06069333e-01
7.09162667e-01 7.12186667e-01 7.15530667e-01 7.19040000e-01
7.22752000e-01 7.26901333e-01 7.31968000e-01 7.38757333e-01
7.45813333e-01 9.90922667e-01 9.95402667e-01 9.97248000e-01
9.98304000e-01 9.98848000e-01 9.99301333e-01 9.99632000e-01
9.99749333e-01 9.99834667e-01 9.99893333e-01 9.99957333e-01
9.99968000e-01 9.99978667e-01 1.00000000e+00 1.00000000e+00]
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('images/03.jpeg',1)
cv2.imshow('src',img)
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)
#计算累计概率
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('gray',gray)
cv2.waitKey(10000)
彩色直方图均衡化
import cv2
import numpy as np
import matplotlib.pyplot as plt
from _testcapi import test_widechar
img=cv2.imread('images/03.jpeg',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(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)
countB[index_b] =countB[index_b]+1
countG[index_b] =countG[index_g]+1
countR[index_b] =countR[index_r]+1
for i in range(0,255):
countB[i] = countB[i]/(height * width)
countG[i] = countG[i]/(height * width)
countR[i] = countR[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+countB[i]
sum_G =sum_G+countG[i]
sum_R =sum_R+countR[i]
countB[i]=sum_B
countG[i]=sum_G
countR[i]=sum_R
#计算映射表
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(countB[i]*255)
map_g[i] = np.uint16(countG[i]*255)
map_r[i] = np.uint16(countR[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('src',dst)
cv2.waitKey(10000)
亮度增强
公式: p=p+40
import cv2
import numpy as np
img=cv2.imread('images/03.jpeg',1)
imgInfo=img.shape
height= imgInfo[0]
width=imgInfo[1]
cv2.imshow('yuantu',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)+40
gg=int(g)+40
rr=int(r)+40
if bb>255:
bb=255
if gg>255:
gg=255
if rr>255:
rr=255
dst[i,j] =(bb,gg,rr)
cv2.imshow('src',dst)
cv2.waitKey(100000)
我弟确实比以前白了。。。
磨皮美白
'''
Created on 2018年5月26日
@author: hongqiangwang
'''
import cv2
img =cv2.imread('images/03.jpeg',1)
cv2.imshow('src',img)
#双边滤波 自带api
dst = cv2.bilateralFilter(img,15,35,35)
cv2.imshow('meibai',dst)
cv2.waitKey(100000)
可以说是很明显了.弟弟说自己变得很美。
高斯滤波
import cv2
img =cv2.imread('images/lena.jpeg',1)
cv2.imshow('src',img)
#双边滤波
dst= cv2.GaussianBlur(img,(5,5),1.5)
cv2.imshow('meibai',dst)
cv2.waitKey(100000)
左图一些坏掉的点,被消除了(这貌似叫消除噪声?),但是右图变得非常模糊。
均值滤波
'''
均值 6*6 [6*6] /36 =mean mean->p
'''
import cv2
import numpy as np
img =cv2.imread('images/lena.jpeg',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 2
for n in range(-3,3):
(b,g,r) =img[i+m,j+n]
sum_b=sum_b+int(g)
sum_g=sum_g+int(g)
sum_r=sum_r+int(g)
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('meibai',dst)
cv2.waitKey(100000)
中值滤波
'''
均值 6*6 [6*6] /36 =mean mean->p
'''
import cv2
import numpy as np
img =cv2.imread('images/lena.jpeg',1)
cv2.imshow('src',img)
imgInfo =img.shape
height= imgInfo[0]
width=imgInfo[1]
img =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
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=0
for m in range(-1,2):
for n in range(-1,2):
gray =img[i+m,j+n]
collect[k]=gray
k=k=1
for k in range(0,9):
pl=collect[k]
for t in range(k+1,9):
if pl<collect[t]:
mid=collect[t]
collect[t]=pl
pl=mid
dst[i,j]=collect[4]
cv2.imshow('meibai',dst)
cv2.waitKey(100000)
完全不晓得这是什么鬼 ···过段时间研究一下,先立下flag