Counting black pixels by thresholding

I’d like to count the black pixels and the percentage of those through setting up an automated threshold, so that whichever image I upload, it can calculate the ratio of black pixels. I’ve started with THRESH_BINARY+THRESH_TRIANGLE thresholds, but other types of threshold algorithms may be suitable (I haven’t tried it yet). I have a sample image that I obtained by a software and I know its black-pixel ratio as 10%


The problem is I get 6% for 10%-black pixel ratio image. The code is like this:

img = cv2.imread('f01.jpeg',0)

# thresholding
ret,th = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_TRIANGLE)

# find number of black pixels
white_pix = cv2.countNonZero(th)

# find total number of pixels
tot_pix = img.size

# find number of white pixels
black_pix = tot_pix-white_pix

# calculate black pixel ratio        
ratio = black_pix/tot_pix

what is the value of ret?
what is the value of img.size?
what is the value of img.shape?


How do you get this result?

and why do you think your picture contains 10% black pixels? what makes you sure about that?

I made this image with a sofware so that it has 10% black phase.

Actually, this code calculates as 6%. It should calculate as 10% because I created this image with 10% black phase in another software.

ret: 253.0
img.size: 690032
img.shape: (854, 808)

you read a jpg image it’s not a black white image, it’s a grey image. Can you post original image?

This is original image from software. Maybe I can save it in different format. Or, I don’t know how, maybe I can convert this image to black white image.

that picture simply DOES NOT have 10% black area.

the code isn’t at fault really. the threshold calculated to be 253 (near perfect white) is bad however. since your picture has some shades of gray, that’ll give a slightly different result compared to if you had used threshold 128 or something similarly “gray”.

there’s really no reason to use any “adaptive” method. just set the threshold to a fixed 128 and it’s going to be good.

Doesn’t suppose to be… I’ll check it anyway :thinking: