Image Histogram
下面那个是p(rk)是概率密度函数。
横坐标灰度等级,纵坐标是各个像素的个数。
直方图性质:
1.无空间信息
2.直方图与图像一对多关系(不同的图像可能有相同的直方图。)
3.可叠加性(全图与子图像),即图像可以由多个子图叠加而成
归一化:
因为目标函数是均匀的,所以P(s)=1,因为那个像素的个数是必定不为0的。
(运算时四舍五入)
eg:0.19在数值上离0.14近,所以安排到1/7处。
变化后基本均匀变化
可以看见均衡化后的图片天空出现了伪轮廓,因为变化时几个等级的灰度均衡化到一个灰度,另外几个灰度又均衡化到了另一个灰度,就会出现灰度差异明显的情况,即灰度的不连续变化,造成了天空的伪轮廓。
反变化:
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的尺寸
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的影子又能看到狒狒的影子
而第四个直接相加的已经失真
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
display
推荐阅读
-
Css3之background-image的深层次理解
-
Neat image pro(图片降噪磨皮滤镜软件)滤镜使用方法 Neat image pro滤镜使用教程
-
如何在双向绑定的Image控件上绘制自定义标记(wpf)
-
【题解】hdu1506 Largest Rectangle in a Histogram
-
jQuery中:image选择器用法实例教程
-
vue的style绑定background-image的方式和其他变量数据的区别详解
-
WPF 给Button按钮加小图标图片Image
-
教你利用Python玩转histogram直方图的五种方法
-
Neat Image磨皮功能如何使用?Neat Image详细教程(针对初学者)
-
Python3实现转换Image图片格式