點運算: 基於直方圖的對比度增強
阿新 • • 發佈:2018-11-01
點運算: 基於直方圖的對比度增強
引言
影象處理–>空間域處理–>點運算。
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");
}