# Looking for ways to speed up pixel scanning

So I am trying to implement a pixel scanner, where I go through every pixel and check if it is white (the image has already been threshold-ed at this point) and if it is white get the pixel's respective x and y coordinate which I use to calculate distances. So far I have been doing it the double for-loop way, and it is adding significant slowdowns compared to the rest of my pipeline. I would like to speed this up. I have looked into using cv::findNonZero(), it gives me a vector of cv::Point, when I try and access the vector at some interation like vec[ i ] the output is [ rowValue, colValue ] which is expected but I don't know how to access the "rowValue" or "colValue" independently that I need in order to calculate distances. I have heard about using cv::LUT() but I'm having some trouble understanding how to use it. Thanks is advanced and let me know if more info is needed. Code below:

   cv::Mat W; // approx 1000 x 1000
for (int i = 0; i < W.cols; i++)
{
for (int j = 0; j < W.rows; j++)
{
cv::Scalar pixelColor = counter.at<uchar>(j, i);
if (pixelColor.val[0] == 255)
{
// pixelLocations are defined as a ROS message, A B C D are constants
// used to calculate distances in meters
pixelLocation.x = (A * i) + B; // distance in x direction relative to robot
pixelLocation.y = (C * j) + D; // distance in front of robot
}
}
}

edit retag close merge delete

use parallel_loop _body

( 2019-03-21 03:13:32 -0500 )edit

Sort by » oldest newest most voted

So I managed to ultilize the cv::findNonZero() function, to get the coordinates of the white pixels.

cv::Mat A;
std::vector<cv::Point> pixelCoordinates;
std::vector<int> xp, yp;
cv::findNonZero(A, pixelCoordinates);
for (size_t i = 0; i < pixelCoordinates.size(); i++)
{
xp.push_back(pixelCoordinates[i].x);
yp.push_back(pixelCoordinates[i].y);
}

more

use .at<uchar>(j,i) would be slowly, try use

(faster) do something scanline-like scan

    for (int i = 0; i < W.rows; i++)  //row first!
{
*uchar data=W.ptr(i);

for (int j = 0; j < W.cols; j++)
{
//do something with data[j];
}
}


or

(fastest) if your mat is continuous you can treat it as 1-d array

uchar* data = (uchar*) W.data;

for(int i=0; i< W.cols*W.rows;i++)
{
//do something with data[i];
}

more

Official site

GitHub

Wiki

Documentation