如何使用opencv从矩阵向量构造图像

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用opencv从矩阵向量构造图像相关的知识,希望对你有一定的参考价值。

我正在将图像分割成矩形区域,我找到了一些有用的代码,允许我这样做,但是,我无法弄清楚如何操纵每个单独的区域,并将它们重新组合成一个形状具有相同原始尺寸的新完整图像。我对c ++和opencv都很陌生,所以任何帮助都会非常感激。

目前,所有矩形都存储在std::vector<cv::Mat> *blocks中。

我想要每个矩形的值,并能够操纵它们的原因是因为我打算稍后将它们解析为某些输出。

这是将图像分割成矩形的代码:

    if(img.cols % colDivisor == 0 && img.rows % colDivisor == 0){
        for(int y = 0; y < img.cols; y += img.cols/colDivisor){
            for(int x = 0; x < img.rows; x += img.rows/rowDivisor){
                blocks->push_back(img(cv::Rect(y, x, (img.cols / colDivisor), (img.rows / rowDivisor))).clone());
                rectangle(maskImg, cv::Point(y,x), cv::Point(y + (maskImg.cols / colDivisor) - 1, x + (maskImg.rows / rowDivisor) - 1), CV_RGB(255, 0, 0), 1);
                cv::imshow("Image", maskImg);

我可以像这样操纵所选图像的BGR值:

    std::vector<cv::Mat> m;
    ...
    cv::Mat image2 =m[9]; //Random rect
    std::vector<cv::Mat> channels;
    cv::split(image2, channels);
    cv::Scalar avg1 = cv::mean(channels[0]);
    cv::Scalar avg2 = cv::mean(channels[1]);
    cv::Scalar avg3 = cv::mean(channels[2]);
    std::cout << "Blue channel: " << avg1[0] << std::endl << "Green channel: " << avg2[0] << std::endl << "Red channel: " <<  avg3[0] << std::endl;
    image2.setTo(cv::Scalar(avg1[0], avg2[0], avg3[0]));
    cv::imshow("BGRTEST", image2);

从上面的代码中可以看出,我成功地能够操作单个区域,但是,我想遍历每个区域并对其应用平均BGR值。

我怎么能这样做?

我尝试使用c ++迭代器,如下所示:

for(std::vector<cv::Mat>::iterator it = blocks->begin(); it != blocks->end(); ++it){

}

但是,我不确定如何实现这样的事情。

提前致谢!

答案

假设原始任务是将图像分割成矩形块并在其上应用一些运算符,则有一种更简单的方法。

OpenCV具有相当方便的感兴趣区域概念。您可以选择图像的某个区域并将其用作图像。您在那里执行的操作将显示在原始图像中。

您正在使用感兴趣的区域,但您复制它,然后计划合并您获得的小图像。这不仅在计算方面浪费,而且使代码更复杂。

以下是您如何利用您感兴趣的区域:

for(int y = 0; y < img.cols - 30; y += 30) {
    for(int x = 0; x < img.rows - 30; x += 30) {
        cv::Mat roi = img(cv::Rect(y, x, 30, 30));
        std::vector<cv::Mat> channels;
        cv::split(roi, channels);
        cv::Scalar avg1 = cv::mean(channels[0]);
        cv::Scalar avg2 = cv::mean(channels[1]);
        cv::Scalar avg3 = cv::mean(channels[2]);
        roi.setTo(cv::Scalar(avg1[0], avg2[0], avg3[0]));
    }
}

我已经复制了你的处理并且改变了计算子图像的方式。

以上是关于如何使用opencv从矩阵向量构造图像的主要内容,如果未能解决你的问题,请参考以下文章

如何获取矩阵二范数 opencv

OpenCV基础---图像存储器(Mat类)

opencv六通道矩阵乘法

《学习opencv》笔记——矩阵和图像操作——cvCrossProduct and cvCvtColor

从 3 通道彩色图像的原始数据加载 Opencv 矩阵

如何创建矩阵向量来存储大量图像?