彩色图像高斯反向投影
一:介绍
图像反向投影的最终目的是获取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文章
1095浏览量
42157 -
投影
+关注
关注
0文章
146浏览量
25273 -
图像分割
+关注
关注
4文章
182浏览量
18674
原文标题:彩色图像高斯反向投影
文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
【GM-3568JHF开发板免费体验】OpenCV开发环境安装和计数程序开发
基于LockAI视觉识别模块:C++轮廓检测
基于LockAI视觉识别模块:C++多模板匹配
基于LockAI视觉识别模块:C++使用图像的统计信息
基于LockAI视觉识别模块:C++图像的基本运算
基于LockAI视觉识别模块:C++图像的基本运算
基于LockAI视觉识别模块:C++图像采集例程
基于LockAI视觉识别模块:C++图像采集例程
创建了用于OpenVINO™推理的自定义C++和Python代码,从C++代码中获得的结果与Python代码不同是为什么?
请问Lightcrafter4500 EVM能否工作在120Hz、彩色(RGB:888)视频模式?
DLP投影不同bit位图像时,曝光和周期的设置问题求解
DLP4500怎么确定投影仪开始投影的同时相机的c++代码开始运行?
源代码加密、源代码防泄漏c/c++与git服务器开发环境

关于彩色图像高斯反向投影基于OpenCV的C++代码
评论