如何进行每元素比较并根据结果进行不同的操作

时间:2013-08-27 11:56:58

标签: c++ opencv matrix

我在C ++中使用OpenCV而且我坚持一点。我需要做以下事情:

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

for循环对于1000x750图像需要100+ ms。我不想使用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循环外,是否有人知道处理此问题的任何函数?

1 个答案:

答案 0 :(得分:1)

您可能需要查看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模块我相信你可以进一步减少第二次,但遗憾的是我目前没有一个合适的显卡连接到我当前的系统。