欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Image Histogram

程序员文章站 2022-07-07 22:53:10
...

Image Histogram

下面那个是p(rk)是概率密度函数。

Image Histogram

横坐标灰度等级,纵坐标是各个像素的个数。

直方图性质:

1.无空间信息

2.直方图与图像一对多关系(不同的图像可能有相同的直方图。)

3.可叠加性(全图与子图像),即图像可以由多个子图叠加而成

 

Image Histogram

Image Histogram

Image Histogram

Image Histogram

Image Histogram

归一化:

Image Histogram

Image Histogram

Image Histogram

Image Histogram

因为目标函数是均匀的,所以P(s)=1,因为那个像素的个数是必定不为0的。

Image Histogram(运算时四舍五入)

Image Histogram

Image Histogram

Image Histogram

eg:0.19在数值上离0.14近,所以安排到1/7处。

Image Histogram

变化后基本均匀变化

Image Histogram

Image Histogram

可以看见均衡化后的图片天空出现了伪轮廓,因为变化时几个等级的灰度均衡化到一个灰度,另外几个灰度又均衡化到了另一个灰度,就会出现灰度差异明显的情况,即灰度的不连续变化,造成了天空的伪轮廓。

Image Histogram

反变化:

Image Histogram

several instances:

1.转换成负片效果(L-1-对应像素值)

# Author imagean
#!/usr/bin/python
# -*- coding:utf-8
import cv2 as cv
import numpy as np
from  matplotlib import pyplot as plt
img2 = np.zeros((256,256,3), np.uint8)#无符号八位整型,表示范围是[0, 255]的整数
img1 = cv.imread("/home/image/Pictures/lena256.jpg")#默认读取三通道
img2[:] = 255 - img1[:]#负片效果,对整个区间进行运算时,不用把三个:全写上,写一个也行


imgcolor = cv.imread("/home/image/Pictures/bottle.png")
print(imgcolor.shape)
imgtemp = np.zeros((imgcolor.shape[0],imgcolor.shape[1],3),np.uint8)#不知道图片的尺寸时调用shape来初始化
(b,g,r) = cv.split(imgcolor)#CV是bgr的顺序,要转化成matplotlib的rgb顺序
imgcolor= cv.merge((r,g,b))
imgtemp[:,:,:] = 255 -imgcolor[:,:,:]
img =[img1,img2,imgcolor,imgtemp]
titles =['256-gary image','oppsite image','24-bit image ','opposite image']
for i in range(4):
    plt.subplot(1,4,i+1)
    plt.imshow(img[i])
    plt.yticks()
    plt.xticks()
    plt.title(titles[i])
plt.show()

运行结果如下:

输出bottle.jpg的尺寸

Image Histogram

Image Histogram


2.图像融合

dst = cv.addWeighted(src1, alpha, src2, beta,gamma, dst, dtype)

此函数的功能就是加权融合图像,每个像素点的像素是两种源图片的对应像素点的像素加权算出来的,融合公式如下:

dst = alpha*src1 + beta*src2 + gamma 

参数说明:

src1:插入的第一个图片;
src2:插入的第二个图片;
alpha:double类型,加权系数,是src1图片的融合占比 ;
beta:double类型,加权系数,是src2图片的融合占比;
gamma:double类型,加权后图像的偏移量;
dst:输出图像;
dtype:默认为-1。

plt.imshow()的cmap(调色板)参数请refer to this article

# Author imagean
#!/usr/bin/python
# -*- coding:utf-8
# opencv read image is BGR channel,and matplot read is RGB

import cv2 as cv
from matplotlib import pyplot as plt
import  numpy as np

# two images addweighted and simple add
imglena = cv.imread("/home/image/Pictures/lena512color.jpg")
(r,g,b)= cv.split(imglena)
img1 = cv.merge([b,g,r])#转换成rgb通道顺序
imgbaboon = cv.imread("/home/image/Pictures/baboon.jpg")
(r,g,b)= cv.split(imgbaboon)
img2 = cv.merge([b,g,r])

#相加的两个图片尺寸必须一致

img3 = cv.addWeighted(img1,0.6,img2,0.4,gamma=0)#第一幅图的权重是0.6,第二幅图的权重是0.4,偏移量为0
img4 = np.zeros(img3.shape,np.uint8)
img4[:,:,:] = img1[:,:,:] + img2[:,:,:]
images = [img1,img2,img3,img4]
titles = ['lena','baboon','maxture Image',' simple + Image']
for i in range(4):
   plt.subplot(2,2,i+1),plt.imshow(images[i],cmap='gray')#cmap就是调色板
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

运行结果:

可看到第三个加权融合的图片中既能看到lena的影子又能看到狒狒的影子

而第四个直接相加的已经失真

Image Histogram


 3.直方图均衡化

先来看一下会用到的几个函数:

1.计算时间

getTickCount():用于返回从操作系统启动到当前所经的计时周期数,看名字也很好理解,get Tick Count(s)。 

getTickFrequency():用于返回CPU的频率。get Tick Frequency。这里的单位是秒,也就是一秒内重复的次数。

即 总次数/一秒内重复的次数 = 时间(s) 

2.绘制直方图

利用plt.hist()绘制直方图

参数interpret:

    matplotlib.pyplot.hist(  
    x, bins=10, range=None, normed=False,   
    weights=None, cumulative=False, bottom=None,   
    histtype=u'bar', align=u'mid', orientation=u'vertical',   
    rwidth=None, log=False, color=None, label=None, stacked=False,   
    hold=None, **kwargs)  

x : (n,) array or sequence of (n,) arrays

这个参数是指定每个bin(箱子)分布的数据,对应x轴

bins : integer or array_like, optional

这个参数指定bin(箱子)的个数,也就是总共有几条条状图

normed : boolean, optional

If True, the first element of the return tuple will be the counts normalized to form a probability density, i.e.,n/(len(x)`dbin)

这个参数指定密度,也就是每个条状图的占比例比,默认为1

color : color or array_like of colors or None, optional

这个指定条状图的颜色

3.numpy的高阶函数histogram()

想要看懂还是得先去看看上面的理论知识

戳这里

再康康这里

4.np.hstack()将参数元组的元素数组按水平方向进行叠加

form one array,但数组间的元素互不干扰。refer to this essay

# Author imagean
#!/usr/bin/python
# -*- coding:utf-8
# opencv read image is BGR channel,and matplot read is RGB
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

names = "/home/image/Pictures/lena.jpg"
img = cv.imread(names,0)
(H,W)=img.shape#高(垂直长度),宽(水平长度)
pixel = H * W

def display(files):
    cv.namedWindow("hist-imgs", 0)
    cv.resizeWindow("hist-imgs",3*W,H)
    cv.imshow("hist-imgs", np.hstack(files))

def opencvdef(img):
    # opencv own's equlization function
    t1 = cv.getTickCount()
    eq = cv.equalizeHist(img)#cv的直方图均衡函数
    t2 = cv.getTickCount()
    T1 = (t2 - t1) / cv.getTickFrequency()
    print("Opencv Histogram() Time consuming is ", T1,'second')
    files.append(eq)#加入列表

#手动均衡化
def own(img):
    # bins is gray volume ,wide 0~255 ,hist is  every gray volume numbers
    t1 =cv.getTickCount()
    hist,bins = np.histogram(img.flatten(), 256, [0, 255])
    LUT = np.zeros(256,np.uint8)
    LUT[0] =1.0 *hist[0] / pixel *255
    sumnums = hist[0]
    for i in range(1,256):
        #s[i]= sum of gray form 0 to i
        sumnums =sumnums +hist[i]
        # LUT is equliztion array  = (255 X s[i])
        LUT[i] = np.uint8(1.0*sumnums /pixel *255)
    temps =np.zeros((H,W),np.uint8)
    for i in range(H ):
        for j in range(W ):
            temps[i,j] =LUT[img[i,j]]
    t2 = cv.getTickCount()
    T2 = (t2 - t1) / cv.getTickFrequency()
    print("Own Histogram() Time consuming is ", T2,'second')

    files.append(temps)
    pltshow(files)

    display(files)
    cv.waitKey(0)

def pltshow(files):
    for i in range(3):
        plt.subplot(2,3,i+1),plt.imshow(files[i], cmap='gray', interpolation='bicubic')
        plt.xticks([]),plt.yticks([])#remove 刻度
    for i in range(3):
        hist, bins = np.histogram(files[i].flatten(), 256, [0, 255])
        plt.subplot(2,3,4+i)
        #flatten()将图像展开成一维数组
        plt.hist(files[i].flatten(),bins=256,range=[0,255],color='red')
        plt.xlim(0, 255),plt.ylim(0, hist.max()+1)#坐标轴范围,hist.max()即为所有像素的频数中最大的一个
    plt.show()

if __name__ == '__main__':
    files =[img]
    opencvdef(img)
    own(img)

运行结果:

pltshow

Image Histogram

display

Image Histogram

 

相关标签: CV