灰度变换
灰度变换其实是操作图片的对比图,来让图片细节能更好被人眼识别。做灰度变换的目的,是让图片数据更加简单,计算机能更好的识别图片。
import cv2
import sys
import os
import matplotlib.pyplot as plt
//bgr格式转换为rgb
def trans2show(img):
return cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
//显示原图
img=cv2.imread("tangsan.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
plt.figure(figsize=(11,11))
plt.imshow(trans2show(img))
plt.show()
显示灰度图
plt.figure(figsize=(8,8))
plt.imshow(gray,cmap='gray')
plt.show()
反色变换
#反色变换
reverse_c=img.copy()
rows=img.shape[0]
cols=img.shape[1]
deeps=img.shape[2]
for i in range(rows):
for j in range(cols):
for d in range(deeps):
//每个像素取反色
reverse_c[i][j][d]=255-reverse_c[i][j][d]
plt.figure(figsize=(16,8))
cv2.imwrite("tangsan_img_reverse.jpg",cv2.hconcat([img,reverse_c]))
plt.imshow(trans2show(cv2.hconcat([img,reverse_c])))
plt.show()
灰度图的反色变换
#反色变换
reverse_c=gray.copy()
rows=gray.shape[0]
cols=gray.shape[1]
for i in range(rows):
for j in range(cols):
reverse_c[i][j]=255-reverse_c[i][j]
cv2.imwrite("tangsan_img_reverse.jpg",cv2.hconcat([gray,reverse_c]))
plt.figure(figsize=(16,8))
plt.imshow(trans2show(cv2.hconcat([gray,reverse_c])))
plt.show()
gamma变换,伽马变换
变换的基本形式为:
c和γ为正常数
对于不同的γ值,有不同的曲线
通过以上曲线图:
gamma值小于1时,会拉伸图像中灰度级较低的区域,同时会压缩灰度级较高的部分
gamma值大于1时,会拉伸图像中灰度级较高的区域,同时会压缩灰度级较低的部分
#伽马变换
#img = cv2.cvtColor(img,cv2.COLOR_RGB2BRG)
gamma_c=dog.copy()
rows=dog.shape[0]
cols=dog.shape[1]
deeps=dog.shape[2]
for i in range(rows):
for j in range(cols):
for d in range(deeps):
gamma_c[i][j][d]=pow(gamma_c[i][j][d]/255,0.5)*255.0
cv2.imwrite("tangsan_img_gamma_c.jpg",cv2.hconcat([dog,gamma_c]))
os.system("open tangsan_img_gamma_c.jpg")
plt.figure(figsize=(16,8))
plt.imshow(trans2show(cv2.hconcat([dog,gamma_c])))
plt.show()
这里需要注意的是色值是0~255,需要使用归一化后操作gamma变化,再恢复回RGB色值。
可以看到暗的图片会变得更加光亮。
人类对光度的感应,并不是线性变化的,人对0~0.2的光度比较敏感,越暗人就越敏感,
gamma变换是为了让人分辨得更舒服
可以参照下图
灰度直方图
直方图可以表示出图片色值分布。如果是灰度图的直方图,可以直接看出图片的明暗 。
# 直方图
import numpy as np
hist = np.zeros(256)
rows = img.shape[0]
cols = img.shape[1]
for i in range(rows):
for j in range(cols):
tmp = gray[i][j]
hist[tmp]=hist[tmp]+1
plt.plot(hist)
plt.show()
直方图均衡化
直方图每个点的计算公式,可以看出0~255范围内直方图的y值 /图片大小的积分,L-1 = 255。
hist = np.zeros(256)
#import pdb
#pdb.set_traoce()
img = cv2.imread("hist.png")
rows = img.shape[0]
cols = img.shape[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
for i in range(rows):
for j in range(cols):
tmp = gray[i][j]
hist[tmp]=hist[tmp]+1
这一段就是计算积分的运算
//像素归一化
trans = hist/(rows*cols)*255
//不断去更新和前一个值的和,积分计算求和
for i in range(1,len(trans)):
trans[i]=trans[i-1]+trans[i]
gray_h = gray.copy()
for i in range(rows):
for j in range(cols):
gray_h[i][j] = int(trans[gray[i][j]])
plt.figure(figsize=(10,10))
plt.imshow(cv2.vconcat([gray,gray_h]),cmap='gray')
plt.title("scr and Histogram Equalization")
plt.show()
可以看一下均衡后的直方图
hist_h=np.zeros(256)
for i in range(rows):
for j in range(cols):
tmp = gray_h[i][j]
hist_h[tmp]=hist_h[tmp]+1
plt.plot(hist_h)
plt.show()
其实cv已经提供了函数去实现直方图均衡化。
equalizeHist(src_gray, dst);
输入灰度图,第二参数是得到直方图均衡化图片。当然这个是C++的方法啦。python的方法自己查阅一下就可以了
直方图均衡化,是否能够调整色值图片让其更对比度更好。
gamma变换和直方图,都是想让图片调整图片的亮暗,而直方图均衡化,是让图片能够色值更加均衡,增加图像全局的对比度。跟进直方图数据判定图片过暗或者过量来使用gamma变换来调整图片亮暗