3

I have an input image as given below. enter image description here

I need to get total percentage and count of green and white pixels in each row of image with specific rowwise as output. I have tried code for getting percentage and count for single row. And it is given below:

import cv2
import numpy as np
from PIL import Image

img_s = Image.open('img_15.png')
width, height = img_s.size
total_pixels= width * height


# load image
img = cv2.imread('img_15.png')

# convert to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)

# create mask for green color in hsv
# green is 60 in opencv
lower = (40,100,100)
upper = (100,255,255)
mask = cv2.inRange(hsv, lower, upper)

# count non-zero pixels in mask
count=np.count_nonzero(mask)
count_z = np.sum(mask == 0)
print("Total pixels:", total_pixels)
print('green count:', count, 'green %:', '{0:.2f}%'.format((count/total_pixels * 100)))
print('white count:', count_z, 'white %', '{0:.2f}%'.format((count_z/total_pixels * 100)))

# save output
cv2.imwrite('img_15_mask.png', mask)

# Display various images to see the steps
cv2.imshow('mask',mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

I need to extend this for each rows instead for a single row.

1 Answers1

2

I think you want something like this. The basic idea is to use np.sum() with axis=1 to tally the non-zero elements (i.e. green pixels) in each row:

#!/usr/bin/env python3

import cv2
import numpy as np

# Load image and get dimensions
img = cv2.imread('EBlso.png')
h, w = img.shape[:2]
total_pixels = h * w

# Convert to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Create mask for green color in HSV
# Green is 60 in OpenCV
lower = (40,100,100)
upper = (100,255,255)
mask = cv2.inRange(hsv, lower, upper)
cv2.imwrite('mask.png', mask)

# Count non-zero pixels in mask
count   = np.count_nonzero(mask)
count_z = total_pixels - count
print(f'Total pixels: {total_pixels}')
print(f'Green count: {count}, green %: {count*100/total_pixels:.2f}')
print(f'White count: {count_z}, white % {count_z*100/total_pixels:.2f}')

# Calculate row-wise stats
GreensPerRow = np.sum(mask>0, axis=1)

for row, greens in enumerate(GreensPerRow):
   print(f'Row: {row}, nGreen: {greens}, pcntGreen: {greens*100/w:.2f}')

Sample Output

Total pixels: 197100
Green count: 82942 green %: 42.08%
White count: 114158 white % 57.92%
Row: 0, nGreen: 0, pcntGreen: 0.00
Row: 1, nGreen: 0, pcntGreen: 0.00
Row: 2, nGreen: 0, pcntGreen: 0.00
Row: 3, nGreen: 0, pcntGreen: 0.00
Row: 4, nGreen: 0, pcntGreen: 0.00
Row: 5, nGreen: 0, pcntGreen: 0.00
Row: 6, nGreen: 0, pcntGreen: 0.00
Row: 7, nGreen: 0, pcntGreen: 0.00
Row: 8, nGreen: 0, pcntGreen: 0.00
Row: 9, nGreen: 0, pcntGreen: 0.00
Row: 10, nGreen: 0, pcntGreen: 0.00
Row: 11, nGreen: 0, pcntGreen: 0.00
Row: 12, nGreen: 0, pcntGreen: 0.00
Row: 13, nGreen: 0, pcntGreen: 0.00
Row: 14, nGreen: 386, pcntGreen: 71.48
Row: 15, nGreen: 387, pcntGreen: 71.67
...
...

Note that there is no real need to use HSV colourspace here, because your greens, with rgb(76,175,80), are readily distinguishable from your whites, with rgb(255,255,255), by thresholding the red or blue channel on, say 128.

Note that I have ignored grey pixels on the assumption that, not being green, they are white. You can easily correct for that assumption if incorrect.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432