基于高斯模型的彩色图像反向投影

简介: 一:介绍图像反向投影的最终目的是获取ROI然后实现对ROI区域的标注、识别、测量等图像处理与分析,是计算机视觉与人工智能的常见方法之一。图像反向投影通常是彩色图像投影效果会比灰度图像效果要好,原因在于彩色图像带有更多对象细节信息,在反向投影的时候更加容易判断、而转为灰度图像会导致这些细节信息丢失、从而导致分割失败。

一:介绍

图像反向投影的最终目的是获取ROI然后实现对ROI区域的标注、识别、测量等图像处理与分析,是计算机视觉与人工智能的常见方法之一。图像反向投影通常是彩色图像投影效果会比灰度图像效果要好,原因在于彩色图像带有更多对象细节信息,在反向投影的时候更加容易判断、而转为灰度图像会导致这些细节信息丢失、从而导致分割失败。最常见的是基于图像直方图特征的反向投影。我们这里介绍一种跟直方图反向投影不一样的彩色图像反向投影方法,通过基于高斯的概率分布公式(PDF)估算,反向投影得到对象区域,该方法也可以看做最简单的图像分割方法。缺点是对象颜色光照改变和尺度改变不具备不变性特征。所以需要在光照度稳定情况下成像采集图像数据。在这种情况下使用的高斯概率密度公式为:
这里写图片描述

1.输入模型M,对M的每个像素点(R,G,B)计算I=R+G+B
r=R/I, g=G/I, b=B/I
2. 根据得到权重比例值,计算得到对应的均值 与标准方差
3. 对输入图像的每个像素点计算根据高斯公式计算P(r)与P(g)的乘积
4. 归一化之后输出结果,即为最终基于高斯PDF的反向投影图像

二:代码实现

代码实现是基于OpenCV 3.2完成的C++代码,首先加载模型对象,计算出均值与标准方差以后,把均值与标准方差作为参数代入上述高斯概率分布公式,对每个像素点的每个通道值求取可能性值,然后求各个通道的可能性乘积作为该点的PDF,得到图像就是反向投影图像,以此为模板,可以得到分割图像。实现图像分割。完整的代码显示如下:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace 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);

    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);
    return 0;
}

三:运行效果
模型图
这里写图片描述
原图
这里写图片描述
反向投影图像
这里写图片描述
最终得到分割出来的鲜花对象图像
这里写图片描述

欢迎继续关注本博客,只分享干货,不止于代码!

目录
相关文章
|
5月前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
530 0
|
6月前
|
算法 计算机视觉
OpenCV高斯差分技术实现图像边缘检测
OpenCV高斯差分技术实现图像边缘检测
|
11月前
|
计算机视觉 Python
图像的傅里叶变换(二)
图像的傅里叶变换(二)
100 0
|
11月前
|
数据安全/隐私保护 Python
图像的傅里叶变换(一)
图像的傅里叶变换
103 0
|
编解码 Android开发 计算机视觉
多分辨率找图sift和直方图
牙叔教程 简单易懂
251 0
|
机器学习/深度学习 传感器 算法
【图像去噪】基于高斯滤波+均值滤波+中值滤波+双边滤波滤波实现图像去噪(含信噪比)附Matlab代码
【图像去噪】基于高斯滤波+均值滤波+中值滤波+双边滤波滤波实现图像去噪(含信噪比)附Matlab代码
|
资源调度 算法 API
OpenCV_06 图像平滑:图像噪声+图像平滑+滤波
由于图像采集、处理、传输等过程不可避免的会受到噪声的污染,妨碍人们对图像理解及分析处理。常见的图像噪声有高斯噪声、椒盐噪声等。
136 0
|
资源调度 算法 机器人
图像特征提取与描述_角点特征02:SIFT算法+SURF算法
前面两节我们介绍了Harris和Shi-Tomasi角点检测算法,这两种算法具有旋转不变性,但不具有尺度不变性,以下图为例,在左侧小图中可以检测到角点,但是图像被放大后,在使用同样的窗口,就检测不到角点了。
209 0
|
资源调度 计算机视觉
CV10 图像模糊(均值、高斯、中值、双边滤波)
当我们只想得到感兴趣的物体时,通过图像模糊,可以将那些尺寸和亮度较小的物体过滤掉,较大的物体则易于检测。除了降低噪声,这就是图像平滑(模糊)的另一个重要应用:减少噪点,突出ROI,以便目标提取。
334 0
|
编解码 资源调度 算法
CV学习笔记-尺度不变特征变换(SIFT)
CV学习笔记-尺度不变特征变换(SIFT)
511 0
CV学习笔记-尺度不变特征变换(SIFT)