Working with regions in opencv?

asked 2016-05-26 04:14:19 -0600

friend gravatar image

Hello, currently I’m in the training phase of opencv. I have previously worked with another image processing-library. In that library you were working with regions. This brings an extreme time advantage. Does something similar exists in opencv?

For example in opencv a normal threshold followed by an erosion with a circular mask of 200 px takes approximately 7 seconds. (On a small VGA-Image)

Thanks for replies in advance.

edit retag flag offensive close merge delete

Comments

200px is it radius? Can you show your code. What is your platform?

LBerger gravatar imageLBerger ( 2016-05-26 04:35:31 -0600 )edit

I am using c++, visual studio 13, opencv 3.1. I think 200px is the diameter.

Code snippet:

Mat elementCirc = getStructuringElement(MORPH_ELLIPSE, cv::Size(200, 200));

Mat closed = Mat();

cv::morphologyEx(roi, closed, cv::MORPH_CLOSE, elementCirc, cv::Point(-1, -1), 1);

friend gravatar imagefriend ( 2016-05-26 04:56:39 -0600 )edit

Can you give size of roi?

LBerger gravatar imageLBerger ( 2016-05-26 09:01:20 -0600 )edit

The contour diameter is 130 px. And it is as a circular object.

link text

friend gravatar imagefriend ( 2016-05-26 09:25:14 -0600 )edit

in release 1.17s in debug 15s with this program

    Mat roi=cv::imread("oeaP4zP.png",CV_LOAD_IMAGE_GRAYSCALE);;

    Mat elementCirc = getStructuringElement(MORPH_ELLIPSE, cv::Size(200, 200));

    Mat closed = Mat();
    high_resolution_clock::time_point tp1 = std::chrono::high_resolution_clock::now();

    cv::morphologyEx(roi, closed, cv::MORPH_CLOSE, elementCirc, cv::Point(-1, -1), 1);
    high_resolution_clock::time_point tp2 = std::chrono::high_resolution_clock::now();
    duration<double> time_span = duration_cast<duration<double>>(tp2 - tp1);
    cout <<  setprecision(3)<<time_span.count()<<endl;
LBerger gravatar imageLBerger ( 2016-05-26 11:12:39 -0600 )edit

For this simple task, i was thinking of times in the 1 ms range (like in halcon). The opencv standard functions are not time optimized right? What do i have to do for reaching that goal?

friend gravatar imagefriend ( 2016-05-27 03:26:46 -0600 )edit

I think you should check if it is exactly same kernel. You opencv withcuda if you want to improve speed. I have some difficulty to understand speed ratio of 100

LBerger gravatar imageLBerger ( 2016-05-27 06:17:31 -0600 )edit

Kernal should be the same. I'll have a look at cuda. I am sceptical, because in Halcon the GPU advantage was not that huge. Perhaps it is different in opencv.

friend gravatar imagefriend ( 2016-05-27 09:00:56 -0600 )edit

At the moment i have no access to a cuda GPU. But i tried to program my own erode, which is faster using bigger masks but still by far too slow. Perhaps you have an idea for optimization?

cv::threshold(channels[2], threshed, (int)numericRedThresh->Value, 255, THRESH_BINARY);

int eroval = (int)nmrc_erosion->Value;

time1 = clock();

//Standard erode

Mat opencvEroImg;

Mat mask = getStructuringElement(MORPH_ELLIPSE, cv::Size(eroval, eroval));

erode(threshed, opencvEroImg, mask, cv::Point(-1, -1), 1);

time2 = clock();

//Attempt for own erosion

eroval = eroval / 2;

Mat ownEroImg = threshed.clone();

for (int r = 0; r<threshed.rows; r++)<="" p="">

{

for (int c = 0; c<threshed.cols; c++)<="" p="">

{

int test = threshed.at<char>(r, c);

//Black?

if (test == 0)

{

...

friend gravatar imagefriend ( 2016-06-08 08:40:00 -0600 )edit

int ri = threshed.at<char>(r, c + 1);

int le = threshed.at<char>(r, c - 1);

int up = threshed.at<char>(r - 1, c);

int dw = threshed.at<char>(r + 1, c);

int ul = threshed.at<char>(r - 1, c - 1);

int ur = threshed.at<char>(r - 1, c + 1);

int dl = threshed.at<char>(r + 1, c - 1);

int dr = threshed.at<char>(r + 1, c + 1);

if (le == 0 & ri == 0 & up == 0 & dw == 0 & ul == 0 & ur == 0 & dl == 0 & dr == 0)

{

 //No circle needed

  }

  else

  {

circle(ownEroImg, CvPoint(c, r), eroval, 0, -1, LINE_8, 0);

  }

}

}

}

time3 = clock();

time1 = time2 - time1;

time2 = time3 - time2;

imshow("opencvEro", opencvEroImg); imshow("ownEro", ownEroImg);

friend gravatar imagefriend ( 2016-06-08 08:44:10 -0600 )edit