c++ - 如何进行逐元素比较并根据结果做不同的操作

标签 c++ opencv matrix

我在 C++ 中使用 OpenCV,我卡在了一个点上。我需要执行以下操作:

if(src(I) < aNumber)
     do operation1
else
     do operation2

对于 1000x750 的图像,For 循环需要 100 多毫秒。我不想使用 for 循环,因为它会花费很多时间。我想将一个(某些)OpenCV 函数与该函数一起使用,我可以编辑矩阵中的一些值。比如我的数组是

[1 4 5;
 4 6 2;
 3 2 1]

我要:

if(an element of mat < 4)
    pow(element,2)
else
    element--;

根据这个if-else

[1 3 4;
 3 5 4
 9 4 1]

将成为我的结果矩阵。

除了使用两个 for 循环之外,有人知道有什么函数可以处理这个问题吗?

最佳答案

您可能想查看 compare .示例:

//Mat mask; compare(src, 10.0, mask, CMP_LT);
Mat mask = src < 10.0;

根据您希望执行的实际操作,您可以使用比较的结果,否则您可以查看 gpu module .特别是 Per-element Operations .

就我个人而言,我觉得 OpenCV 应该像 MATLAB 一样对待,避免循环,使用矩阵,并尽可能尝试使用内置函数(即使它们只是作为循环实现,它可以节省您输入同样的事情一次又一次)。

编辑:以下是使用循环和内置矩阵运算符完成更新问题中的任务的示例代码:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//#include <opencv2/gpu/gpu.hpp>
using namespace cv;

#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    // Load Image
    Mat matImage = imread("Test.png");

    // Convert to Grayscale
    Mat matGray(matImage.rows, matImage.cols, CV_8UC1);
    cvtColor(matImage, matGray, CV_BGR2GRAY);

    double time, dThreshold = 50.0;
    //int TIMES = 1000;

    //namedWindow("Display", WINDOW_NORMAL);
    //char chKey;

    //imshow("Display", matGray);
    //chKey = '\0'; while (chKey != '') chKey = waitKey(0);

    //----------------------------- Loop Method -------------------------------

    time = (double) getTickCount();

    //for (int k = 0; k < TIMES; k++)
    //{
        Mat matLoop = matGray.clone();

        for (int i = 0; i < matLoop.rows; ++i)
        {
            for (int j = 0; j < matLoop.cols; ++j)
            {
                uchar& unValue = matLoop.at<uchar>(i, j);
                if (unValue < dThreshold)
                    unValue = pow(unValue, 2);
                else
                    unValue--;
            }
        }
    //}

    time = 1000*((double)getTickCount() - time)/getTickFrequency();
    //time /= TIMES;
    cout << "Loop Method Time: " << time << " milliseconds." << endl;

    //imshow("Display", matLoop);
    //chKey = '\0'; while (chKey != '') chKey = waitKey(0);

    //---------------------------- Matrix Method ------------------------------

    time = (double) getTickCount();

    //for (int i = 0; i < TIMES; i++)
    //{
        Mat matMask, matMatrix;

        matMask = matGray < dThreshold;
        bitwise_and(matGray, matMask, matMatrix);
        pow(matMatrix, 2.0, matMatrix);
        subtract(matGray, 1.0, matMatrix, ~matMask);
    //}

    time = 1000*((double)getTickCount() - time)/getTickFrequency();
    //time /= TIMES;
    cout << "Matrix Method Time: " << time << " milliseconds." << endl;

    //imshow("Display", matMatrix);
    //chKey = '\0'; while (chKey != '') chKey = waitKey(0);

    return 0;
}

除了将需要键入的代码行数从 12 行减少到 5 行外,矩阵方法也更快。启用计时循环(使用 TIMES = 1000;),对于中等大小的图像,我得到以下时间:

Loop Method Time: 9.19669 milliseconds.
Matrix Method Time: 2.82657 milliseconds.

使用 gpu 模块我相信你可以进一步减少第二次,但不幸的是我目前没有合适的显卡连接到我当前的系统。

关于c++ - 如何进行逐元素比较并根据结果做不同的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18464710/

相关文章:

python - 如何使用 python 从该矩阵中删除行/列

c++ - 为什么不能在新的初始化程序中省略数组大小?

c++ - 使用c++将Mat转换为opencv中的内存

python - 将单应性应用于整个图像后,如何将2D点转换回去?

matlab - 创建零行和索引一的矩阵

c++ - reshape OpenCV Mat 失败

c++ - 如何使用模板类查询 if(T==int)

python - Cython "Unknown type in template argument"错误

c++ - Sublime Text 2 运行 C++11 代码

python - OpenCV 3 Python - Haar Cascade Upper Body Detector 不适用于半身(腰部向上)照片?