彩色圖像高斯反向投影
一:介紹
圖像反向投影的最終目的是獲取ROI然后實現對ROI區域的標注、識別、測量等圖像處理與分析,是計算機視覺與人工智能的常見方法之一。圖像反向投影通常是彩色圖像投影效果會比灰度圖像效果要好,原因在于彩色圖像帶有更多對象細節信息,在反向投影的時候更加容易判斷、而轉為灰度圖像會導致這些細節信息丟失、從而導致分割失敗。最常見的是基于圖像直方圖特征的反向投影。我們這里介紹一種跟直方圖反向投影不一樣的彩色圖像反向投影方法,通過基于高斯的概率分布公式(PDF)估算,反向投影得到對象區域,該方法也可以看做最簡單的圖像分割方法。缺點是對象顏色光照改變和尺度改變不具備不變性特征。所以需要在光照度穩定情況下成像采集圖像數據。 在這種情況下使用的高斯概率密度公式為:
-
輸入模型M,對M的每個像素點(R,G,B)計算I=R+G+B r=R/I, g=G/I, b=B/I
-
根據得到權重比例值,計算得到對應的均值 與標準方差
-
對輸入圖像的每個像素點計算根據高斯公式計算P(r)與P(g)的乘積
-
歸一化之后輸出結果,即為最終基于高斯PDF的反向投影圖像
二:算法步驟與代碼實現
-
首先加載模型圖像與測試圖像
-
根據模型圖像計算得到每個通道對應的均值與標準方差參數
-
根據參數方差計算每個像素點的PDF值
-
歸一化概率分布圖像-即為反向投影圖像,顯示
-
根據Mask得到最終顏色模型對象分割
完整的基于OpenCV的C++代碼如下:
-
#include
-
#include
-
#include
-
-
using namespace cv;
-
using namespace std;
-
-
int main(int argc, char** argv) {
-
// 加載模型圖像與測試圖像
-
Mat model = imread("D:/gloomyfish/gm.png");
-
if (src.empty() || model.empty()) {
-
printf("could not load image... ");
-
return -1;
-
}
-
imshow("input image", src);
-
-
// 對每個通道 計算高斯PDF的參數
-
// 有一個通道不計算,是因為它可以通過1-r-g得到
-
// 無需再計算
-
Mat R = Mat::zeros(model.size(), CV_32FC1);
-
Mat G = Mat::zeros(model.size(), CV_32FC1);
-
int r = 0, g = 0, b = 0;
-
float sum = 0;
-
for (int row = 0; row < model.rows; row++) {
-
uchar* current = model.ptr
(row); -
for (int col = 0; col < model.cols; col++) {
-
b = *current++;
-
g = *current++;
-
r = *current++;
-
sum = b + g + r;
-
R.at
(row, col) = r / sum; -
G.at
(row, col) = g / sum; -
}
-
}
-
-
// 計算均值與標準方差
-
Mat mean, stddev;
-
double mr, devr;
-
double mg, devg;
-
meanStdDev(R, mean, stddev);
-
mr = mean.at
(0, 0); -
devr = mean.at
(0, 0); -
-
meanStdDev(G, mean, stddev);
-
mg = mean.at
(0, 0); -
devg = mean.at
(0, 0); -
-
int width = src.cols;
-
int height = src.rows;
-
-
// 反向投影
-
float pr = 0, pg = 0;
-
Mat result = Mat::zeros(src.size(), CV_32FC1);
-
for (int row = 0; row < height; row++) {
-
uchar* currentRow = src.ptr
(row); -
for (int col = 0; col < width; col++) {
-
b = *currentRow++;
-
g = *currentRow++;
-
r = *currentRow++;
-
sum = b + g + r;
-
float red = r / sum;
-
float green = g / sum;
-
pr = (1 / (devr*sqrt(2 * CV_PI)))*exp(-(pow((red - mr), 2)) / (2 * pow(devr, 2)));
-
pg = (1 / (devg*sqrt(2 * CV_PI)))*exp(-(pow((green - mg),2)) / (2 * pow(devg, 2)));
-
sum = pr*pg;
-
result.at
(row, col) = sum; -
}
-
}
-
-
// 歸一化顯示高斯反向投影
-
Mat img(src.size(), CV_8UC1);
-
normalize(result, result, 0, 255, NORM_MINMAX);
-
result.convertTo(img, CV_8U);
-
Mat segmentation;
-
src.copyTo(segmentation, img);
-
-
// 顯示
-
imshow("backprojection demo", img);
-
imshow("segmentation demo", segmentation);
-
-
waitKey(0);
-
return 0;
-
}
三:測試圖像與效果演示
藍色矩形框為模型,整個圖像為測試圖像
反向投影結果
分割提取結果
四:總結
大家看了這個例子總是有點怪怪的,總會想起點什么,如果你能想起點什么的話就是GMM,高斯混合模型,高斯混合模型正是在此基礎上進一步演化而來。
審核編輯 :李倩
-
圖像
+關注
關注
2文章
1084瀏覽量
40465 -
投影
+關注
關注
0文章
143瀏覽量
24698 -
圖像分割
+關注
關注
4文章
182瀏覽量
18000
原文標題:彩色圖像高斯反向投影
文章出處:【微信號:CVSCHOOL,微信公眾號:OpenCV學堂】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論