-9

I have this image of a battery:

enter image description here

I would like to determine the dimensions of the battery (in pixels).
The problem I have is that the battery is rotated by an unknown angle.
How can I detect the dimensions of this rotated battery?

I was thinking of these algorithmic steps:

  • First, I would have to convert this image to a black and white image (thresholding).
  • After that, I would have to find a center point and draw a rectangle in the white pixels.
  • Then, I have to turn the rectangle 360 degrees and locate the position of the rectangle (and so the dimensions).

I am somewhat inexperienced, and I would appreciate some guidance as to how to implement these algorithmic stages in Matlab.

Thanks

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
  • 5
    Delete the question. Read some image processing code in Matlab. Try some code. If it doesnt work, come here, post the code and show us what you tried and why it didnt work. – Ander Biguri Aug 26 '15 at 13:53
  • 2
    I think the downvotes were a bit too harsh here, especially considering the quality of the answer. In a similar situation, I wrote this answer: http://stackoverflow.com/questions/29127181/matching-images-with-different-orientations-and-scales-in-matlab/29128507#29128507 - where the OP didn't show much effort, but the question got highly upvoted as well as the answer. To those who downvoted, you should consider removing the downvotes at least. There's a clear double standard here that I don't like. – rayryeng Aug 26 '15 at 15:16
  • 4
    @rayryeng, IMHO, this question deserved a downvote, and still does. I could say the same about the other one, I can only assume it got most of the upvotes after your excellent answer. In my experience, a bad question often get a lot of undeserved upvotes, due to a great answer. IMO, the answer should be upvoted, not the question... Having said that, 8 downvotes seems a bit overkill. But then again, 8 downvotes mean 8 people thought it was bad, not that it's 8 times as bad as a post with only 1 downvote. Just my two cents... – Stewie Griffin Aug 26 '15 at 15:33
  • 1
    And Shai: your answer is awesome! =) – Stewie Griffin Aug 26 '15 at 15:34
  • 2
    @StewieGriffin - I'm inclined to agree with your comment. I can see that now! – rayryeng Aug 26 '15 at 15:34
  • @StewieGriffin thanks! – Shai Jan 24 '16 at 13:58

1 Answers1

39

Consider this as a beginner's tutorial to Matlab image processing. Read the documentation of the commands used and try and understand what they are doing and why.

1. Read the image

Use imread to read the image into a 3D matrix. For convenience, we convert it to double in the range [0..1] using im2double:

>> img = im2double( imread( 'path/to/battety.jpg' ) );

You can check out the size of your img using size command:

>> size( img )
ans =
    1024         768           3

You can see from the result that your image has 1024 rows, 768 columns and 3 channels (Red, Green and Blue).

2. Convert to black and white (a.k.a thresholding)

As you can see the battery is significantly brighter than the background and is colorless. We can select pixels that have large gap between the brightest channel value to darkest channel values as "battery" pixels:

>> bw = (max(img,[],3)-min(img,[],3)) > 0.2;

See max and min for more details.
There are other methods to threshold an image, see graythresh for more details.

Using imshow we can see what we got:

>> imshow(bw,[],'border','tight');

enter image description here

Normally one uses morphological operations to improve thresholding results.
You can use imclose:

>> bw = imclose( bw, ones(25) );

Resulting with:
enter image description here

3. find angle of rotation

A very useful command for processing and working with bw images is regionprops. It allows you to get all sorts of nice properties. You are going to use it to compute the 'Orientation' of the "white"/battery region of your image

>> st = regionprops( bw, 'Orientation' )
st = 
Orientation: 52.8694

As you can see the battery is rotated by 52.8 degrees.
Using imrotate to "straighten" the battery

>> rbw = imrotate( bw, -st.Orientation );

Once the battery is axis-aligned, you can "project" the white pixels onto the horizontal and vertical axes using any:

>> pc = any( rbw, 2 ); %// project all rows into a single column 
>> pr = any( rbw, 1 ); %// project all columns into a single row

Now you need to find the first and last pixels set to 1 in the projections. Use find for that:

>> fx = find( pr, 1, 'first');  %// first x coordinate
>> tx = find( pr, 1, 'last');   %// last x coordinat
>> fy = find( pc, 1, 'first');  %// first y coordinate
>> ty = find( pc, 1, 'last');   %// last y coordinate  

Once you have x,y coordinates of corners, you can plot them on the rotated image:

>> imshow(rbw,[],'border','tight');
>> hold on; 
>> plot( [fx tx tx fx fx], [fy fy ty ty fy], ':r', 'LineWidth',3);

Yields:
enter image description here

And the coordinates are:

>> [fx fy tx ty]
ans =
406   608   866   733

As you can see your battery is (866-406) pixels long and (733-608) pixels wide.

Community
  • 1
  • 1
Shai
  • 111,146
  • 38
  • 238
  • 371