赞
踩
import cv2 import numpy as np # 获取直方图函数 def imaggHist(img,type): # 定义展示的窗口的名称和直方图颜色 # 红色通道的直方图用红色,黄色通道用黄色,蓝色通道用蓝色 color =(255,255,255) windowName="gray" if type==0: windowName="Blue window" color=(255,0,0) elif type==1: windowName = "Green window" color = (0, 255, 0) elif type==2: windowName = "Red window" color = (0, 0, 255) # 通过 calcHist 函数来计算直方图: # 第一个参数为图片数据,第二个参数计算图像的通道,这里是 第一个 # 第三个参数是mask 蒙版,不需要用到,这里是None # 第四个参数是 直方图的size ,这里是256 ,表示有256 个柱子。 # 第五个参数表示直方图中各个像素的值,这里是从0 到 255 。 hist=cv2.calcHist([img],[0],None,[256],[0.0,255.255]) minV,maxV,minL,maxL=cv2.minMaxLoc(hist) # 构造一个空白画布 histimg=np.zeros([256,256,3],np.uint8) for h in range(256): # 像素颜色归一化处理,使得数据在 0 - 255 之间。 intenNormal=int(hist[h]*256/maxV) # 画柱状图,这里用线来表示。 cv2.line(histimg,(h,256),(h,256-intenNormal),color) cv2.imshow(windowName,histimg) #savePic(windowName,histimg) return histimg def main(): img=cv2.imread("img.png",1) # 将图像分成 3 个通道 channels=cv2.split(img) # 对每一个通道求取这个通道的直方图: for i in range(3): imaggHist(channels[i],i) cv2.imshow("old image",img) cv2.waitKey(0) if __name__ == '__main__': main()
# 灰色直方图均匀化 # 本质上是统计每个灰度出现的概率。 import cv2 import numpy as np import matplotlib.pyplot as plt %matplotlib inline # 读取图片 img=cv2.imread("img.png",1) # 转化为灰度图片 gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) imageInfo=img.shape height=imageInfo[0] width=imageInfo[1] mode=imageInfo[2] # 建立灰度值百分比的数组,共有256个灰度值 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]+=1 total=height*width # 算出每个灰度值占灰度值总数的比例,作为直方图的y轴 for i in range(256): count[i]=count[i]/total # 生成一个 从0 到 255范围内256等份的一个数组。 x=np.linspace(0,255,256) y=count # 绘图和展示 plt.bar(x,y,0.9,alpha=1,color='b') plt.show() cv2.waitKey(0)
# 彩色直方图的绘制和灰度直方图绘制没有什么不同 # 区别就是灰度图像是单通道的,,但是彩色图片是三通道的。 import cv2 import numpy as np import matplotlib.pyplot as plt img=cv2.imread("img.png",1) imageInfo=img.shape height=imageInfo[0] width=imageInfo[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(height): for j in range(width): (b,g,r)=img[i,j] b=int(b) g=int(g) r=int(r) count_b[b]+=1 count_g[g]+=1 count_r[r]+=1 total =width*height for i in range(256): count_b[i] = count_b[i] / total count_g[i] = count_g[i] / total count_r[i] = count_r[i] / total x=np.linspace(0,255,256) plt.figure() y_b=count_b plt.bar(x,y_b,0.9,alpha=1,color='b') plt.figure() y_g=count_g plt.bar(x,y_g,0.9,alpha=1,color='g') plt.figure() y_r=count_r plt.bar(x,y_r,0.9,alpha=1,color='r') plt.show() cv2.waitKey(0)
# 灰色直方图均匀化
import cv2
img=cv2.imread("img.png",1)
cv2.imshow("old image",img)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 调用均匀化直方图 API
new_img=cv2.equalizeHist(gray)
cv2.imshow("new image",new_img)
cv2.waitKey(0)
#savePic("gray_equal_hist",result)
# 彩色直方图均匀化 import cv2 img=cv2.imread("img.png",1) cv2.imshow("old image",img) # 通道分解: (b,g,r)=cv2.split(img) # 均匀化: bH=cv2.equalizeHist(b) gH=cv2.equalizeHist(g) rH=cv2.equalizeHist(r) # 通道合成: res=cv2.merge((bH,gH,rH)) cv2.imshow("result image",res) cv2.waitKey(0) #savePic("colour_equal_hist",result)
# YUA 直方图均匀化
import cv2
img=cv2.imread("img.png",1)
cv2.imshow("old image",img)
imgYua=cv2.cvtColor(img,cv2.COLOR_BGR2YCrCb)
channelYUA=cv2.split(imgYua)
channelYUA[0]=cv2.equalizeHist(channelYUA[0])
channels=cv2.merge(channelYUA)
result=cv2.cvtColor(channels,cv2.COLOR_YCrCb2BGR)
cv2.imshow("new img",result)
cv2.waitKey(0)
#savePic("YUAimg",result)
直方图均衡化定义:
直方图均衡化(Histogram Equalization) 又称直方图平坦化,实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较平的分段直方图:如果输出数据分段值较小的话,会产生粗略分类的视觉效果。
相关概念:
以灰度突下你给为例,灰度图像有256 个灰度值,每一个灰度值都有一个频率,表示在图片中出现次数的多少。累计概率就是把灰度值的概率和比这个灰度值小的灰度值的概率进行累加得到的概率值。
例如有三个灰度值:1 2 3,概率分别为 0.2,0.5,0.3 ,则1的累计频率就是0.2,2的累计频率就是 0.7,3的累计频率就是1。
当前图像的灰度值乘当前灰度值的累计频率,将得到的灰度值替换原来的灰度值。
# 灰度图像的直方图均衡化算法实现 import cv2 import numpy as np img=cv2.imread("img.png",1) imageInfo=img.shape height=imageInfo[0] width=imageInfo[1] count=np.zeros(256,np.float) gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) for i in range(height): for j in range(width): pixel=gray[i,j] index=int(pixel) count[index]+=1 # 计算频率 total=width*height for i in range(256): count[i]=count[i]/total # 将概率替换为累计概率 Sum=float(0) for i in range(256): Sum+=count[i] count[i]=Sum #构架颜色映射表 colorMap=np.zeros(256,np.uint16) for i in range(256): colorMap[i]=count[i]*255 for i in range(height): for j in range(width): pixel=gray[i,j] gray[i,j]=colorMap[np.uint16(pixel)] cv2.imshow("gray",gray) cv2.waitKey(0)
# 彩色直方图均衡化算法实现 # 彩色图片的均衡化没有什么特别之处,知道彩色图像是三通道就好。 import cv2 import numpy as np img=cv2.imread("img.png",1) imageInfo=img.shape height=imageInfo[0] width=imageInfo[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(height): for j in range(width): (b,g,r)=img[i,j] b=int(b) g=int(g) r=int(r) count_b[b]+=1 count_g[g]+=1 count_r[r]+=1 total =width*height # 分通道统计各个通道上的各个颜色的频率 for i in range(256): count_b[i] = count_b[i] / total count_g[i] = count_g[i] / total count_r[i] = count_r[i] / total # 将概率替换为累计概率 sum_r=float(0) sum_g=float(0) sum_b=float(0) for i in range(256): sum_b+=count_b[i] count_b[i]=sum_b sum_g += count_g[i] count_g[i] = sum_g sum_r += count_r[i] count_r[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(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) # 构造新图: new_img=np.zeros((height,width,3),np.uint8) for i in range(height): for j in range(width): (b,g,r)=img[i,j] new_img[i,j]=(map_b[b],map_g[g],map_r[r]) cv2.imshow("gray",new_img) cv2.waitKey(0)
# 生成一个损坏的图片,损坏的图片如下所示: import cv2 import numpy as np img=cv2.imread("img.png",1) for i in range(50,100): img[i,49]=(0,0,255) img[i,50]=(0,0,255) img[i,51]=(0,0,255) for i in range(25,75): img[74,i]=(0,0,255) img[75,i]=(0,0,255) img[76,i]=(0,0,255) cv2.imshow("damage image",img) cv2.imwrite("damage.png",img) cv2.waitKey(0)
# 修补这个图片 import cv2 import numpy as np # 生成损坏的图片 img=cv2.imread("damage.png",1) imageInfo=img.shape height=imageInfo[0] width=imageInfo[1] points=np.zeros((height,width,1),np.uint8) #构造破损部位的图像蒙版,这里和当时生成破损图片的位置是一致的。 for i in range(50,100): points[i,49]=255 points[i,50]=255 points[i,51]=255 for i in range(25,75): points[74,i]=255 points[75,i]=255 points[76,i]=255 # 通过opencv 的api impaint 函数来进行图像的修补: # 第一个参数是损坏的图片,第二个参数是图片损坏部分的蒙版(图片损坏部分的描述) # 第三个参数是 算法计算的时候考虑每个点圆形邻域的半径,这里写3 # 第四个参数是一个标志,是opencv 的一个常量 fixedImg=cv2.inpaint(img,points,3,cv2.INPAINT_TELEA) cv2.imshow("mask",points) cv2.imshow("damage image",img) cv2.imshow("fixed image",fixedImg) cv2.waitKey(0) # 可以看到修补之后的图片和破损之前的图片相差不大。
修补图片用的蒙版:
修补后的图像:
# 图片亮度增强算法十分简单 # 只要将图片的颜色值增加一个固定的值即可,固定的值越大,提亮效果越明显 import cv2 img=cv2.imread("img.png",1) imageInfo=img.shape height=imageInfo[0] width=imageInfo[1] # 假设提亮40个等级的颜色值 addition=40 cv2.imshow("old image",img) for i in range(height): for j in range(width): (b,g,r)=img[i,j] b=int(b)+addition g=int(g)+addition r=int(r)+addition if b>255: b=255 if g>255: g=255 if r>255: r=255 img[i,j]=(b,g,r) cv2.imshow("new image",img) cv2.waitKey(0)
修改前:
修改后:
# 人像美白功能,使用opencv api 实现
import cv2
img=cv2.imread("girl.png",1)
# 使用双边滤波方法来实现人像美白:
dst=cv2.bilateralFilter(img,15,35,35)
cv2.imshow("old image",img)
cv2.imshow("new image",dst)
cv2.waitKey(0)
原图:
优化后:
# 高斯滤波
import cv2
img=cv2.imread("image11.jpg",1)
cv2.imshow("old image",img)
dst=cv2.GaussianBlur(img,(5,5),1.5)
cv2.imshow("new image",dst)
cv2.waitKey(0)
原图:
高斯滤波之后:
# 均值滤波 # 所谓均值滤波的原理就是在一个像素点周围的一片区域内求的改区域的平均值 # 用这个平均值作为这个像素的颜色。下面是算法代码:可以有效的去除一些噪声。 import cv2 import numpy as np img=cv2.imread("image11.jpg",1) cv2.imshow("old image",img) imageInfo=img.shape height=imageInfo[0] width=imageInfo[1] mode=imageInfo[2] 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): for 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("new image",dst) cv2.imwrite("junzhilvbo.png",dst) cv2.waitKey(0)
# 中值滤波的原理很简单 # 选取一个特定的像素范围,将中间像素的像素值设置为范围内的中值。 # 算法实现如下: import cv2 import numpy as np img=cv2.imread("image11.jpg",1) img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) cv2.imshow("old image",img) imageInfo=img.shape height=imageInfo[0] width=imageInfo[1] dst=np.zeros((height,width,1),np.uint8) collect=np.zeros(9,np.uint8) for i in range(1,height-1): for j in range(1,width-1): p=0 for m in range(-1,2): for n in range(-1,2): collect[p]=img[i+m,j+n] p=p+1 for g in range(8): for q in range(0,8-g): if collect[q]
原图:
滤波后:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。