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

简介: 一:介绍图像反向投影的最终目的是获取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;
}

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

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

目录
相关文章
|
网络协议 关系型数据库 MySQL
如何在Android Termux上安装MySQL并实现公网远程访问?
如何在Android Termux上安装MySQL并实现公网远程访问?
537 0
|
12月前
|
Unix Linux Python
在Python中,删除环境变量
在Python中,删除环境变量
697 8
|
8月前
|
人工智能 Java API
阿里云 0 元领取 100 万 Tokens,零门槛体验 DeepSeek-R1 满血版
阿里云开放DeepSeek-R1满血版体验,0门槛领取100万Tokens,参数规模6710亿,性能强劲且完全免费。用户可轻松写代码、做表格、写故事、逻辑推理等。重点是无需任何编程基础,学生党、职场新人皆可使用。通过注册阿里云账号、生成API Key并使用HiFox客户端,即可快速上手体验顶级AI助手的强大功能。限时福利,赶快行动!
|
存储 Kubernetes API
在K8S中,PVC创建和挂载失败原因有哪些?
在K8S中,PVC创建和挂载失败原因有哪些?
|
SQL 数据可视化 关系型数据库
MySQL命令行与可视化工具
MySQL命令行与可视化工具
|
12月前
|
缓存 运维 Ubuntu
掌控软件管理:详解 APT、YUM 和 DNF 的使用方法
掌控软件管理:详解 APT、YUM 和 DNF 的使用方法
1218 0
|
数据可视化 数据挖掘 Python
"揭秘Visium HD黑科技:空间数据分析大揭秘,可视化与整合的艺术之旅!"
【8月更文挑战第20天】近年来,空间转录组技术,特别是Visium HD技术,因其高分辨率与高通量特性,在单细胞生物学领域受到广泛关注。本文通过Python演示了Visium HD数据的全流程分析:从数据准备(读取表达矩阵和空间坐标)、空间数据分析(计算基因表达统计量)、数据可视化(绘制基因表达热图和空间点分布图),到多样本数据整合,为读者提供了实用的分析指南,助力深入探索空间转录组学的奥秘。
342 4
|
Linux Python
Linux离线安装Python依赖包
本文介绍了在Linux环境下离线安装Python依赖包的方法,包括从Python依赖包检索网站下载所需依赖包的压缩文件,上传到Linux服务器,然后通过解压、编译和安装步骤完成依赖包的安装。
1060 0
|
前端开发 Java 网络架构
SpringBoot使用接口下载图片的写法
在Spring Boot中实现图片下载功能涉及定义一个REST接口来发送图片文件。首先,创建`ImageController`类,并在其中定义`downloadImage`方法,该方法使用`@GetMapping`注解来处理HTTP GET请求。方法内部,通过`Files.readAllBytes`读取图片文件到字节数组,再将该数组封装成`ByteArrayResource`。接着,设置`HttpHeaders`以指定文件名为`image.jpg`并配置为附件下载。
722 0
|
NoSQL 网络协议 架构师