OpenCV圖像處理專欄十五 |《一種基於亮度均衡的圖像閾值分割技術》

前言

對於光照不均勻的圖像,用一般的圖像分割方法不能取得滿意的效果。爲了解決這個問題,論文《一種基於亮度均衡的圖像閾值分割技術》提出了一種實用而簡便的圖像分割方法。該方法針對圖像中不一樣亮度區域進行亮度補償,使得整個圖像亮度背景趨於一致後,再進行常規的閾值分割。實驗結果代表,用該方法能取得良好的分割效果。關於常規的閾值分割不是我這篇推文關注的,我這裏只實現前面光照補償的部分。算法的原理能夠仔細看論文。論文原文見附錄。html

算法步驟

  • 若是是RGB圖須要轉化成灰度圖。
  • 求取原始圖src的平均灰度,並記錄rows和cols。
  • 按照必定大小,分爲 個方塊,求出每塊的平均值,獲得子塊的亮度矩陣
  • 用矩陣 的每一個元素減去原圖的平均灰度,獲得子塊的亮度差值矩陣
  • 用雙立方插值法,將矩陣   resize成和原圖同樣大小的亮度分佈矩陣
  • 獲得矯正後的圖像:

代碼實現

Mat speed_rgb2gray(Mat src) {
Mat dst(src.rows, src.cols, CV_8UC1);
#pragma omp parallel for num_threads(12)
for (int i = 0; i < src.rows; i++) {
for (int j = 0; j < src.cols; j++) {
dst.at<uchar>(i, j) = ((src.at<Vec3b>(i, j)[0] << 18) + (src.at<Vec3b>(i, j)[0] << 15) + (src.at<Vec3b>(i, j)[0] << 14) +
(src.at<Vec3b>(i, j)[0] << 11) + (src.at<Vec3b>(i, j)[0] << 7) + (src.at<Vec3b>(i, j)[0] << 7) + (src.at<Vec3b>(i, j)[0] << 5) +
(src.at<Vec3b>(i, j)[0] << 4) + (src.at<Vec3b>(i, j)[0] << 2) +
(src.at<Vec3b>(i, j)[1] << 19) + (src.at<Vec3b>(i, j)[1] << 16) + (src.at<Vec3b>(i, j)[1] << 14) + (src.at<Vec3b>(i, j)[1] << 13) +
(src.at<Vec3b>(i, j)[1] << 10) + (src.at<Vec3b>(i, j)[1] << 8) + (src.at<Vec3b>(i, j)[1] << 4) + (src.at<Vec3b>(i, j)[1] << 3) + (src.at<Vec3b>(i, j)[1] << 1) +
(src.at<Vec3b>(i, j)[2] << 16) + (src.at<Vec3b>(i, j)[2] << 15) + (src.at<Vec3b>(i, j)[2] << 14) + (src.at<Vec3b>(i, j)[2] << 12) +
(src.at<Vec3b>(i, j)[2] << 9) + (src.at<Vec3b>(i, j)[2] << 7) + (src.at<Vec3b>(i, j)[2] << 6) + (src.at<Vec3b>(i, j)[2] << 5) + (src.at<Vec3b>(i, j)[2] << 4) + (src.at<Vec3b>(i, j)[2] << 1) >> 20);
}
}
return dst;
}


Mat unevenLightCompensate(Mat src, int block_Size) {
int row = src.rows;
int col = src.cols;
Mat gray(row, col, CV_8UC1);
if (src.channels() == 3) {
gray = speed_rgb2gray(src);
}
else {
gray = src;
}
float average = mean(gray)[0];
int new_row = ceil(1.0 * row / block_Size);
int new_col = ceil(1.0 * col / block_Size);
Mat new_img(new_row, new_col, CV_32FC1);
for (int i = 0; i < new_row; i++) {
for (int j = 0; j < new_col; j++) {
int rowx = i * block_Size;
int rowy = (i + 1) * block_Size;
int colx = j * block_Size;
int coly = (j + 1) * block_Size;
if (rowy > row) rowy = row;
if (coly > col) coly = col;
Mat ROI = src(Range(rowx, rowy), Range(colx, coly));
float block_average = mean(ROI)[0];
new_img.at<float>(i, j) = block_average;
}
}
new_img = new_img - average;
Mat new_img2;
resize(new_img, new_img2, Size(row, col), (0, 0), (0, 0), INTER_CUBIC);
Mat new_src;
gray.convertTo(new_src, CV_32FC1);
Mat dst = new_src - new_img2;
dst.convertTo(dst, CV_8UC1);
return dst;
}

效果

能夠看到通過這個算法處理以後,亮度確實被均衡了一些,從視覺效果上來看仍是有做用的。node

附錄

  • 論文原文:https://wenku.baidu.com/view/f74cc087e53a580216fcfe52.html?from=search

同期文章


歡迎關注GiantPandaCV, 在這裏你將看到獨家的深度學習分享,堅持原創,天天分享咱們學習到的新鮮知識。( • ̀ω•́ )✧web

有對文章相關的問題,或者想要加入交流羣,歡迎添加BBuf微信:算法

在這裏插入圖片描述


                            


本文分享自微信公衆號 - GiantPandaCV(BBuf233)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。微信

相關文章
相關標籤/搜索