当前位置:   article > 正文

使用opencv 进行图像美化_opencv窗口美化

opencv窗口美化

获取图片直方图(使用opencv API)

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

获取图片直方图(使用原理)

# 灰色直方图均匀化
# 本质上是统计每个灰度出现的概率。
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这里插入图片描述

# 彩色直方图的绘制和灰度直方图绘制没有什么不同
# 区别就是灰度图像是单通道的,,但是彩色图片是三通道的。
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

png
在这里插入图片描述

png

直方图均衡化(使用opencv API)

# 灰色直方图均匀化
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述

# 彩色直方图均匀化

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述

# 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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

直方图均衡化(使用原理与代码)

直方图均衡化定义:

直方图均衡化(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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这里插入图片描述

# 彩色直方图均衡化算法实现
# 彩色图片的均衡化没有什么特别之处,知道彩色图像是三通道就好。
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

在这里插入图片描述

图片修补

# 生成一个损坏的图片,损坏的图片如下所示:
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述

# 修补这个图片
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)
# 可以看到修补之后的图片和破损之前的图片相差不大。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

修补图片用的蒙版:
在这里插入图片描述
修补后的图像:
在这里插入图片描述

图片亮度增强

# 图片亮度增强算法十分简单
# 只要将图片的颜色值增加一个固定的值即可,固定的值越大,提亮效果越明显
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

修改前:
在这里插入图片描述
修改后:
在这里插入图片描述

人像美白(使用opencv API)

# 人像美白功能,使用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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

原图:
在这里插入图片描述
优化后:
在这里插入图片描述

高斯均值滤波

# 高斯滤波
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

原图:
在这里插入图片描述
高斯滤波之后:
在这里插入图片描述

# 均值滤波
# 所谓均值滤波的原理就是在一个像素点周围的一片区域内求的改区域的平均值
# 用这个平均值作为这个像素的颜色。下面是算法代码:可以有效的去除一些噪声。
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这里插入图片描述

中值滤波

# 中值滤波的原理很简单
# 选取一个特定的像素范围,将中间像素的像素值设置为范围内的中值。
# 算法实现如下:
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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

原图:
在这里插入图片描述
滤波后:
在这里插入图片描述

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号