彩色圖像高斯反向投影
點擊上方“小白學(xué)視覺”,選擇加"星標"或“置頂”
重磅干貨,第一時間送達
彩色圖像高斯反向投影
圖像反向投影的最終目的是獲取ROI然后實現(xiàn)對ROI區(qū)域的標注、識別、測量等圖像處理與分析,是計算機視覺與人工智能的常見方法之一。圖像反向投影通常是彩色圖像投影效果會比灰度圖像效果要好,原因在于彩色圖像帶有更多對象細節(jié)信息,在反向投影的時候更加容易判斷、而轉(zhuǎn)為灰度圖像會導(dǎo)致這些細節(jié)信息丟失、從而導(dǎo)致分割失敗。最常見的是基于圖像直方圖特征的反向投影。我們這里介紹一種跟直方圖反向投影不一樣的彩色圖像反向投影方法,通過基于高斯的概率分布公式(PDF)估算,反向投影得到對象區(qū)域,該方法也可以看做最簡單的圖像分割方法。缺點是對象顏色光照改變和尺度改變不具備不變性特征。所以需要在光照度穩(wěn)定情況下成像采集圖像數(shù)據(jù)。在這種情況下使用的高斯概率密度公式為:

輸入模型M,對M的每個像素點(R,G,B)計算I=R+G+B r=R/I, g=G/I, b=B/I
根據(jù)得到權(quán)重比例值,計算得到對應(yīng)的均值 與標準方差
對輸入圖像的每個像素點計算根據(jù)高斯公式計算P(r)與P(g)的乘積
歸一化之后輸出結(jié)果,即為最終基于高斯PDF的反向投影圖像
首先加載模型圖像與測試圖像
根據(jù)模型圖像計算得到每個通道對應(yīng)的均值與標準方差參數(shù)
根據(jù)參數(shù)方差計算每個像素點的PDF值
歸一化概率分布圖像-即為反向投影圖像,顯示
根據(jù)Mask得到最終顏色模型對象分割
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
usingnamespace cv;
usingnamespace std;
int main(int argc, char** argv) {
// 加載模型圖像與測試圖像
Mat src = imread("D:/gloomyfish/gc_test.png");
Mat model = imread("D:/gloomyfish/gm.png");
if(src.empty() || model.empty()) {
printf("could not load image...\n");
return-1;
}
imshow("input image", src);
// 對每個通道 計算高斯PDF的參數(shù)
// 有一個通道不計算,是因為它可以通過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<uchar>(row);
for(int col = 0; col < model.cols; col++) {
b = *current++;
g = *current++;
r = *current++;
sum = b + g + r;
R.at<float>(row, col) = r / sum;
G.at<float>(row, col) = g / sum;
}
}
// 計算均值與標準方差
Mat mean, stddev;
double mr, devr;
double mg, devg;
meanStdDev(R, mean, stddev);
mr = mean.at<double>(0, 0);
devr = mean.at<double>(0, 0);
meanStdDev(G, mean, stddev);
mg = mean.at<double>(0, 0);
devg = mean.at<double>(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<uchar>(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<float>(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);
return0;
}
藍色矩形框為模型,整個圖像為測試圖像

反向投影結(jié)果

分割提取結(jié)果

大家看了這個例子總是有點怪怪的,總會想起點什么,如果你能想起點什么的話就是GMM,高斯混合模型,高斯混合模型正是在此基礎(chǔ)上進一步演化而來。
好消息,小白學(xué)視覺團隊的知識星球開通啦,為了感謝大家的支持與厚愛,團隊決定將價值149元的知識星球現(xiàn)時免費加入。各位小伙伴們要抓住機會哦!

交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~

