Going with our comments, what you can do is create a list of numpy
arrays, where each element is the intensities that describe the interior of the contour of each object. Specifically, for each contour, create a binary mask that fills in the interior of the contour, find the (x,y)
coordinates of the filled in object, then index into your image and grab the intensities.
I don't know exactly how you set up your code, but let's assume you have an image that's grayscale called img
. You may need to convert the image to grayscale because cv2.findContours
works on grayscale images. With this, call cv2.findContours
normally:
import cv2
import numpy as np
#... Put your other code here....
#....
# Call if necessary
#img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Call cv2.findContours
contours,_ = cv2.findContours(img, cv2.RETR_LIST, cv2.cv.CV_CHAIN_APPROX_NONE)
contours
is now a list of 3D numpy
arrays where each is of size N x 1 x 2
where N
is the total number of contour points for each object.
As such, you can create our list like so:
# Initialize empty list
lst_intensities = []
# For each list of contour points...
for i in range(len(contours)):
# Create a mask image that contains the contour filled in
cimg = np.zeros_like(img)
cv2.drawContours(cimg, contours, i, color=255, thickness=-1)
# Access the image pixels and create a 1D numpy array then add to list
pts = np.where(cimg == 255)
lst_intensities.append(img[pts[0], pts[1]])
For each contour, we create a blank image then draw the filled-in contour in this blank image. You can fill in the area that the contour occupies by specifying the thickness
parameter to be -1. I set the interior of the contour to 255. After, we use numpy.where
to find all row and column locations in an array that match a certain condition. In our case, we want to find the values that are equal to 255. After, we use these points to index into our image to grab the pixel intensities that are interior to the contour.
lst_intensities
contains that list of 1D numpy
arrays where each element gives you the intensities that belong to the interior of the contour of each object. To access each array, simply do lst_intensities[i]
where i
is the contour you want to access.
cv2.findContours
certainly does the job for you and it returns a list of(x,y)
coordinates per contour. You can then use these coordinates to index into your image and grab the right intensities. However, I'm not sure how exactly you want to store these intensities. Do you just want a single 1D array of intensities? Do you want to put them into some sort of mask? Can you elaborate how exactly you want these intensities stored? – Namancv2.findContours
, and they're stored in an array. I just want a 1D array of intensity values of all the pixels within that boundary. Also, I'm not sure how I'm supposed to index through. Could you please explain that? – Midrifffor
loop to index through the output ofcv2.findContours
. Then I just usedpxlVal = img[x, y]
to get the pixel values on the boundary of the object (the contours). How would I get the pixels within the boundary? – Midriff