开发者

How to detect an 'image area' percentage inside an image?

Mhh, kinda hard to explain with my poor english ;)

So, lets say I have an image, doesnt matter what kind of (gif, jpg, png) with 200x200 pixel size (total area 40000 pixels)

This image have a background, that can be traspare开发者_C百科nt, or every color (but i know the background-color in advance).

Lets say that in the middle of this image, there is a picture (for keep the example simple lets suppose is a square drawn), of 100x100 pixels (total area 10000 pixels).

I need to know the area percentage that the small square fill inside the image.

So, in i know the full image size and the background-color, there is a way in php/python to scan the image and retrieve that (in short, counting the pixel that are different from the given background)?

In the above example, the result should be 25%

EDIT: this are two image as example (gimped oin the way ;):

How to detect an 'image area' percentage inside an image?

How to detect an 'image area' percentage inside an image?

I need to know the percentage of the green pepper in the whole image (that is 400x400)


from PIL import Image
image = Image.open("pepper.png")
bg = image.getpixel((0,0))
width, height = image.size
bg_count = next(n for n,c in image.getcolors(width*height) if c==bg)
img_count = width*height - bg_count
img_percent = img_count*100.0/width/height

gives 7.361875 for both images


I am assuming the surrounding area has only one colour and the object in the image can have any shape (so you need to find out its coordinates first, right?)

If you can use ImageMagick, it's easy.

  1. Store size of image (40000 Pixels)

  2. Send image to ImageMagick and trim the surrounding area using -trim (description here)

  3. Compare size of resulting image (10000 Pixels) with that of original image

If you can't use ImageMagick, you will have to use GD to crop the surrounding area away. A rough description is in the answer to this question. I'm pretty sure this has been implemented in PHP already, though.


Using Python and PIL (Python Imaging Library) you could try the following (untested - credit goes to the original thread here):

 from PIL import ImageChops

 def trim(im, border):
     bg = Image.new(im.mode, im.size, border)
     diff = ImageChops.difference(im, bg)
     bbox = diff.getbbox()
     if bbox:
         return im.crop(bbox)
     else:
         # found no content
         raise ValueError("cannot trim; image was empty")

And then do your calculations based on width * height (before and after the trim).


It depends a bit on your accuracy requirements and on the presence of the background color in the image. Consider this annoying test case:

  • Make a 400 pt large "G".
  • Make the text white. Hit "Shadow" or "Outline" so it surrounded by black.
  • Put it on a white background.

Pick your effort:

  • You can get a bounding box, which heavily overestimates the size of the 'G' because of the large blank space inside.
  • You can count the white pixels, which heavily underestimates the size of the 'G' because of the many white pixels inside the outline.
  • You can pick a color not in the image, like blue, and run a recursive painter's algorithm from the top left corner. Then you can accurately count the blue pixels.
  • There are faster methods, which are more complicated.

You can usually use PIL (Python Imaging Library) http://www.pythonware.com/products/pil/ to access raw image data from the file formats.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜