Ask Your Question
0

Extracting features with unclean canny detection

asked 2014-09-18 01:13:01 -0600

Icetray gravatar image

Hi Guys!

I performed a canny edge detection on an object and playing with the thresholds, I got the following output: Click here

The topmost rectangle is part of the part which I wish to ignore

The bottom two rectangles are the features I wish to outline in my original image. I know that it maybe possible to use HoughTransform to find the rectangles but I hoping to find a more generic method as my feature may not be of a fixed shape (perhaps using approxPolyDP?).

I'm not sure if it's possible but is it possible to: 1. extract the contours of the image 2. join lines that are close to one another 3. if the lines form a closed loop -> box the object if it's just stray lines, ignore.

If it is, can anyone give me the rough outline of how to do it? If it's not, do you guys have any other suggestions?

Thanks in advance!

edit retag flag offensive close merge delete

Comments

1

It would be good if you share your actual image or other similar image before coming into conclusion.

Balaji R gravatar imageBalaji R ( 2014-09-18 01:26:33 -0600 )edit

I don't have it with me now but it's a very polished surface similar to this :https://img1.etsystatic.com/042/0/6723474/il_340x270.621018835_tj4e.jpg

It would be similar to trying to box the raised portion in the middle of the button. Hope it helps! :)

Icetray gravatar imageIcetray ( 2014-09-18 01:35:38 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2014-09-18 01:30:23 -0600

Hi,

Depending what the original image is there may be better filtering to perform first to get a more solid result. Below is a brief answer to your questions.

1 extract the contours of the image

this link is a tutorial on applying contours to an image after a canny edge detection. For more information on contours see this link

2 join lines that are close to one another

For this you might want to use a convex hull, see this link

3 if the lines form a closed loop -> box the object if it's just stray lines, ignore.

This should occur in step two when you are selecting the contours.

edit flag offensive delete link more

Comments

I'll give this a shot! Thanks!

I don't have the original image at the moment but if you're wondering what it looks like, it's a very polished surface similar to this:

https://img1.etsystatic.com/042/0/6723474/il_340x270.621018835_tj4e.jpg

It would be similar to trying to box the raised portion in the middle of the button.

Icetray gravatar imageIcetray ( 2014-09-18 01:38:46 -0600 )edit

I gave the above a shot but I think my lines are too broken for it to work properly.

Contour before Hull: Click here After Hull (black): Click here

Is there a way to perhaps join lines that are close together? Perhaps with less broken lines I can get a better result? Or maybe you guys have other ideas. :)

Icetray gravatar imageIcetray ( 2014-09-18 05:34:57 -0600 )edit

Could you share the code you used? You are going to have to filter the points from the contours, I will see if I can give you some pointers.

Messina Vision Systems gravatar imageMessina Vision Systems ( 2014-09-18 08:14:16 -0600 )edit

It's quite messy to be honest. I have a whole bunch of other attempts inside that I commended out. But basically the breakdown is:

image >> Gaussian Blur (3,3) >> Canny >> Canny to Binary >> dilates and errodes to thicken lines >> findCountors

If I can somehow extend lines until 2 lines meet, I think I can get away with it.

Icetray gravatar imageIcetray ( 2014-09-18 08:28:48 -0600 )edit

There is no easy way to extend the lines that I know of, you will need to go through the points of the contours and perform the operation, below is something I just googled to do so. Filtering contours can be a messy task because you have to compare different contours points. My suggestion would be to play around for a better convex hull result.

for(size_t i=0; i<contours.size(); i++) { // use contours[i] for the current contour

for(size_t j=0; j<contours[i].size(); j++) {

//use contours[i][j] for current point

}}

Messina Vision Systems gravatar imageMessina Vision Systems ( 2014-09-18 17:47:06 -0600 )edit

What the data type for contours[i]? I tried int/double/float point = contours[i] but all failed. Error 4 error C2440: 'initializing' : cannot convert from 'std::vector<cv::Point,std::allocator<_Ty>>' to 'float'

Icetray gravatar imageIcetray ( 2014-09-19 08:05:53 -0600 )edit

contours is vector<vector<Point>>

contours[i] is vector<Point>

contours[i][j] is Point so to access the value you will need to use contours[i][j].x and contours[i][j].y

Messina Vision Systems gravatar imageMessina Vision Systems ( 2014-09-20 07:11:16 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2014-09-18 01:13:01 -0600

Seen: 4,008 times

Last updated: Sep 18 '14