1. 程式人生 > >點運算: 基於直方圖的對比度增強

點運算: 基於直方圖的對比度增強

點運算: 基於直方圖的對比度增強

引言

影象處理–>空間域處理–>點運算。

1、影象顯示與儲存原理

<center>
<img src="" width="60%" height="60%">     #更改圖片大小並居中

- RGB

- CMY(K)

- HSV

- CIE-XYZ

儲存原理

2、影象增強的目標

  • 改善影象的視覺效果;
  • 轉換為更適合於人或機器分析處理的形式;
  • 突出對人或機器分析有意義的資訊;
  • 抑制無用資訊, 提高影象的使用價值;
  • 包括影象銳化, 平滑、 去噪, 灰度調整(對比度增強)

影象處理方法

3、點運算(基於直方圖的對比度增強)

直方圖統計:

直方圖均衡化:

  • 直方圖均衡化是指: 利用影象直方圖對對比度進行調整的方法。
  • 直方圖均衡化通常用來增加許多影象的區域性對比度, 尤其是當影象的有用資料的對比度相當接近的時候。
  • 直方圖均衡化以後, 亮度可以更好地在直方圖上分佈。 這樣就可以用於增強區域性的對比度而不影響整體的對比度, 直方圖均衡化通過有效地擴充套件常用的亮度來實現這種功能。
  • 直方圖均衡化,實質上是對影象進行非線性拉伸,重新分配各個灰度單位中的畫素點數量, 使一定灰度範圍畫素點數量的值大致相等。

自適應直方圖均衡(AHE):

  • 直方圖均衡的經典演算法對整幅影象的畫素使用相同的變換, 如果影象中包括明顯亮的或者暗的區域, 則經典演算法作用有限。
  • 自適應直方圖均衡(AHE) 演算法通過對區域性區域進行直方圖均衡, 來解決上述問題。
    • 移動模板在原始圖片上按特定步長滑動;
    • 每次移動後, 模板區域內做直方圖均衡, 對映後的結果賦值給模板區域內所有點;
    • 每個點會有多次賦值, 最終的取值為這些賦值的均值。

CLAHE:
CLAHE參考部落格。一定要看。

  • AHE會過度放大影象中相對均勻區域的噪音, 可採用限制對比度自適應直方圖均衡(CLAHE) 。

  • 與普通的自適應直方圖均衡相比, CLAHE的不同地方在於直方圖修剪過程, 用修剪後的直方圖均衡影象時, 影象對比度會更自然。

  • 整體思想就是把直方圖高的部分擷取來將整個直方圖墊高。

  • 小黑點的灰度直接由對映函式計算得到;
  • 粉色區域內點的灰度由對映函式計算而得;
  • 綠色區域內點的灰度由由相鄰2塊灰度對映值線性插值而得;
  • 其他區域所有點的灰度由相鄰4塊的灰度對映值雙線性插值而得。

CLAHE演算法步驟:

  • 1.影象分塊, 以塊為單位;
  • 2.先計算直方圖, 然後修剪直方圖, 最後均衡;
  • 3.遍歷操作各個影象塊, 進行塊間雙線性插值;
  • 4.與原圖做圖層濾色混合操作。 (可選)

4、程式

直方圖均衡化(HE)

Cpp+opencv

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;

int main( )
{
	// 載入源影象
	Mat srcImage, dstImage;
	srcImage = imread( "1.jpg", 1 );
	if(!srcImage.data ) { printf("讀取圖片錯誤,請確定目錄下是否有imread函式指定圖片存在~! \n"); return false; } 

	// 轉為灰度圖並顯示出來
	cvtColor( srcImage, srcImage, CV_BGR2GRAY );
	imshow( "原始圖", srcImage );

	// 進行直方圖均衡化
	equalizeHist( srcImage, dstImage );

	// 顯示結果
	imshow( "經過直方圖均衡化後的圖", dstImage );
	waitKey(0);
	return 0;

}

在這裡插入圖片描述
其他OpenCV影象增強演算法實現參考部落格

自適應直方圖均衡化(AHE)

限制對比度自適應直方圖均衡化(CLAHE)

Python+opencv

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('timg.jpg',0) #直接讀為灰度影象
res = cv2.equalizeHist(img)

clahe = cv2.createCLAHE(clipLimit=2,tileGridSize=(10,10))
cl1 = clahe.apply(img)

plt.subplot(131),plt.imshow(img,'gray')
plt.subplot(132),plt.imshow(res,'gray')
plt.subplot(133),plt.imshow(cl1,'gray')

plt.show()

在這裡插入圖片描述
cpp+opencv

#include "opencv2/opencv.hpp"    
#include <iostream>    
 
using namespace cv;
using namespace std;
 
void main()
{
	Mat inp_img = cv::imread("D:\\proMatlab\\vessel_edge_extration\\image\\7.jpg");
	if (!inp_img.data) {
		cout << "Something Wrong";
	}
	namedWindow("Input Image", CV_WINDOW_AUTOSIZE);
	imshow("Input Image", inp_img);
 
	Mat clahe_img;
	cvtColor(inp_img, clahe_img, CV_BGR2Lab);
	vector<cv::Mat> channels(3);
	split(clahe_img, channels);
 
	Ptr<cv::CLAHE> clahe = createCLAHE();
	// 直方圖的柱子高度大於計算後的ClipLimit的部分被裁剪掉,然後將其平均分配給整張直方圖   
	clahe->setClipLimit(4.); // (int)(4.*(8*8)/256)  
	//clahe->setTilesGridSize(Size(8, 8)); // 將影象分為8*8塊  
	Mat dst;
	clahe->apply(channels[0], dst);
	dst.copyTo(channels[0]);
	//
	clahe->apply(channels[1], dst);
	dst.copyTo(channels[1]);
	clahe->apply(channels[2], dst);
	dst.copyTo(channels[2]);
	merge(channels, clahe_img);
 
	Mat image_clahe;
	cvtColor(clahe_img, image_clahe, CV_Lab2BGR);
 
	namedWindow("CLAHE Image", CV_WINDOW_AUTOSIZE);
	imshow("CLAHE Image", image_clahe);
	imwrite("out.jpg", image_clahe);
	waitKey();
	system("pause");
}

在這裡插入圖片描述