【问题标题】:Draw rectangles like voting on a heatmap像在热图上投票一样绘制矩形
【发布时间】:2014-10-21 08:29:19
【问题描述】:

我想在 opencv 中创建 mat 文件并将它们初始化为零(所有像素为黑色)。因此我使用 用于初始化目的:

Mat img = Mat::zeros(image.rows, image.cols, CV_8UC1);

之后,我得到了一些矩形,其位置位于该图像内,我想绘制矩形白色的对应区域。如何在 mat 文件中绘制区域?

我有以下函数来绘制矩形。但是我想绘制所有矩形而不仅仅是边界。

static Mat image_draw(Mat image, vector<Rect> rect, CvScalar  color){

for(int i = 0; i < faces.size(); i++)
{
    Point pt1(rect[i].x + rect[i].width, rect[i].y + rect[i].height);
    Point pt2(rect[i].x, rect[i].y);
    rectangle(image, pt1, pt2, color, 5, 8, 0);
}
return image;

}

我想要做的确切的事情是为我的矩形创建一个热图,以便重叠的边界框具有比简单的非重叠矩形更高的值(接近 255)。我改变厚度:

img =  image_draw( img, rects,  cvScalar(255, 102, 255, 0), -1);

变量 rects 包含 0 到 10 个矩形。我想以某种方式聚合矩形绘图。不只是重新绘制矩形。

如果我想使其功能化,是这样的:编辑最终解决方案:

static Mat heatmap2(Mat image1, vector<Rect> faces, CvScalar  color, int thickness) {

cv::Mat heatmap(image1.rows, image1.cols, CV_8U,cv::Scalar(0));

for(int i = 0; i < faces.size(); i++)
{
    cv::Mat temp(image1.rows, image1.cols , CV_8U, cv::Scalar(0));
    Point pt1(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
    Point pt2(faces[i].x, faces[i].y);
    rectangle(temp, pt1, pt2, color, thickness, 8, 0);
    heatmap+=temp;
}

return heatmap;

}

【问题讨论】:

    标签: c++ image opencv


    【解决方案1】:

    试试这个:

        cv::Mat heatmap(200,300,CV_8U,cv::Scalar(0));
        {
            cv::Mat temp(200,300,CV_8U,cv::Scalar(0));
            cv::Rect r(10,20,30,30);
            cv::rectangle(temp,r,cv::Scalar(100),-1);
            heatmap+=temp;
        }
        {
            cv::Mat temp(200,300,CV_8U,cv::Scalar(0));
            cv::Rect r(20,25,30,30);
            cv::rectangle(temp,r,cv::Scalar(100),-1);
            heatmap+=temp;
        }
        cv::imshow("Heatmap",heatmap);
        cv::waitKey();
    

    结果:

    【讨论】:

    • 如果我想把它功能化?
    • 好吧,想想看,这是个小问题。非常基本的东西(函数和类)。
    • 如果我想为热图添加颜色会有什么变化?
    • CV_8UC3, cv::Scalar(blue,green,red)
    • 当您只需要一个子部分时,添加整个矩阵的工作但非常不理想
    【解决方案2】:

    来自官方 OpenCV 文档(检查 here),“Thickness 组成矩形的线。负值,如 CV_FILLED,意味着函数必须绘制一个填充的矩形。”

    所以给厚度一个负值,比如 -

    rectangle(image, pt1, pt2, color, -1, 8, 0);
    

    更新 在您的代码中使用这些行,

    for(int i=0; i < rect.size(); i++)
                for( int y = rect[i].y; y < rect[i].y + rect[i].height; y++ )
                    for( int x = rect[i].x; x < rect[i].x + rect[i].width; x++ )
                    {
                        image.at<uchar>(y,x) =
                                saturate_cast<uchar>( image.at<uchar>(y,x) + 50 );
                    }
    

    这里每个Rect都会增加50的强度,当达到255的时候就保持255。

    输入图像

    输出图像

    2个重叠矩形

    【讨论】:

    • 是的,这是一个选项。然而,我想要做的确切的事情是为我的矩形创建一个热图,以便重叠的边界框具有比简单的非重叠矩形更高的值。
    • 你如何计算“更高的价值”?您是否已经有一个 Rect 大小的 Mat 对象,您想将其粘贴到您的图像上还是要计算它?
    • 我的意思是如果我有两个重叠的边界框,我希望第一个绘制一个矩形,例如灰度值 50,第二个重叠的矩形添加一个灰度值 50,以便重叠区域更白比非重叠区域。基本上我有多个分类器,我想找到分类器决策重叠的位置。
    【解决方案3】:

    只需对您的代码稍作修改即可:

    static void draw_rectangles(Mat image, vector<Rect> faces) {
    
    cv::Mat heatmap(image.rows, image.cols, CV_8U,cv::Scalar(0));
    
    for(int i = 0; i < faces.size(); i++)
    {
        cv::Mat temp = heatmat(faces[i]); // gives you a submatrix of your heatmap pointing at the location of your rectangle
        temp += 10; // add 10 grey levels to the existing values. This also modifies heatmap as side-effect
    }
    imshow("heatmap", heatmap);
    waitKey(0);
    

    【讨论】:

    • 如果我想为热图添加颜色会有什么变化?
    • 使用查找表cv::lut
    • 能否澄清您的评论?
    • 检查超链接上的文档。查找表有助于将某个灰度级像素值与 BGR 三元组相关联,因此您可以将“热图”可视化为真实的热图,即矩阵中的最高值偏红
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2020-05-08
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    相关资源
    最近更新 更多