Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need a faster way to convert a cv::Mat into 1 dimensional vector form

I have a for loop the takes an OpenCV Mat object of n x n dimensions, and returns a Mat object of n^2 x 1 dimensions. It works, but when I time the method it takes between 1 and 2 milliseconds. Since I am calling this method 3 or 4 million times its taking my program about an hour to run. A research paper I'm referencing suggests the author was able to produce a program with the same function that ran in only a few minutes, without running any threads in parallel. After timing each section of code, the only portion taking >1 ms is the following method.

static Mat mat2vec(Mat mat)
{

Mat toReturn = Mat(mat.rows*mat.cols, 1, mat.type());
float* matPt;
float* retPt;
for (int i = 0; i < mat.rows; i++) //rows
    {
        matPt = mat.ptr<float>(i);
        for (int j = 0; j < mat.row(i).cols; j++) //col
        {
            retPt = toReturn.ptr<float>(i*mat.cols + j);
            retPt[0] = matPt[j];
        }
    }
return toReturn;
}

Is there any way that I can increase the speed at which this method converts an n x n matrix into an n^2 x 1 matrix (or cv::Mat representing a vector)?

that solved most of the problem @berak, its running a lot faster now. however in some cases like below, the mat is not continuous. Any idea of how I can get an ROI in a continuous mat?

my method not looks like this:

static Mat mat2vec(Mat mat)
{
if ( ! mat.isContinuous() )
{ 
    mat = mat.clone();
}
return mat.reshape(1,2500);
}

Problems occur at:

Mat patch = Mat(inputSource, Rect((inputPoint.x - (patchSize / 2)), (inputPoint.y -        (patchSize / 2)), patchSize, patchSize));
Mat puVec = mat2vec(patch);
like image 626
user3813455 Avatar asked Jul 28 '14 18:07

user3813455


People also ask

What is a CV :: mat?

In OpenCV the main matrix class is called Mat and is contained in the OpenCV-namespace cv. This matrix is not templated but nevertheless can contain different data types. These are indicated by a certain type-number. Additionally, OpenCV provides a templated class called Mat_, which is derived from Mat.

What is Vec3b OpenCV?

Vec3b is the abbreviation for "vector with 3 byte entries" Here those byte entries are unsigned char values to represent values between 0 .. 255.

What is CV_64F?

CV_64F is the same as CV_64FC1 . So if you need just 2D matrix (i.e. single channeled) you can just use CV_64F. EDIT. More generally, type name of a Mat object consists of several parts.

What is scalar OpenCV?

ScalarRepresents a 4-element vector. The type Scalar is widely used in OpenCV for passing pixel values. In this tutorial, we will use it extensively to represent BGR color values (3 parameters). It is not necessary to define the last argument if it is not going to be used.


1 Answers

assuming that the data in your Mat is continuous, Mat::reshape() for the win.

and it's almost for free. only rows/cols get adjusted, no memory moved. i.e, mat = mat.reshape(1,1) would make a 1d float array of it.

like image 148
berak Avatar answered Sep 29 '22 05:09

berak