一、彩色图片直方图
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)
效果图如下: