2

I'm thresholding an image which gives me some white regions. And I have a pixel location that's located in one of these regions. I'm using opencv connectedComponentsWithStats to get the regions and then find if the pixel is in any of these regions. How can I do that?

On that note, is there a better way of finding in which thresholded region that pixel is located?

Yasin
  • 609
  • 1
  • 10
  • 22

2 Answers2

2
numLabels, labelImage, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity, cv2.CV_32S)

numLabels = number of labels or regions in your thresholded image

labelImage = matrix or image containing unique labels(1, 2, 3..) representing each region, background is represented as 0 in labelImage.

stats = stats is a matrix of stats which contains information about the regions.

centroids = centroid of each region.

In your case, you can use the labelImage to find out the unique label value on the pixel coordinate to find out in which region it lies in.

Sanchit.Jain
  • 568
  • 2
  • 7
  • Thanks for the answer. Just to clarify for myself, what exactly labelImage represent? Is it a multi-dimensional array of all pixels for each region? If so, why is numLabels way different from len(labelImage)? e.g. 4 vs 375 – Yasin Oct 15 '19 at 07:21
  • labelImage represents unique labels for your each region. It marks same unique label to connected pixels carrying a corresponding unique label. Here each region is given a unique number starting from 1 to n. As the background does not belong to any region it is given '0' label just to differentiate with other regions. labelImage is a multidimensional array. When you do len(labelImage) you are getting length of numpy array which is height of your image. What you can try here is numpy.unique to get unique values present in the labelImage. – Sanchit.Jain Oct 15 '19 at 07:47
  • I think i'm starting to understand how it works. Another question. How can I access/display a certain label? For example I have 4 labels and I want to display label 1. – Yasin Oct 15 '19 at 07:56
  • To access coordinate values what you can do is use np.where(labelImage == 1). To display you can plot these points on blank image to get a region of only that coordinates. – Sanchit.Jain Oct 15 '19 at 08:03
  • And yes to visualize you can use matplotlib.pyplot.imshow function to view labelImage to get more insights on how does it look like. – Sanchit.Jain Oct 15 '19 at 08:05
  • Thanks again for the help on this. Is there a way to do that visualization using opencv and numpy only? – Yasin Oct 16 '19 at 05:08
  • Yes you can use cv2.imshow(window_name, image) method to display your output image – Sanchit.Jain Oct 16 '19 at 05:29
  • Let me ask the question better. I'm using `np.uint8(np.where(labels == 1))` to pick my label, but now I need to put this label over a background that's same size as my source image so I can see it correctly in context. Meaning a white background like `np.uint8(255*np.ones_like(labels))` But I don't know how to do so as they have mismatching dimension. – Yasin Oct 16 '19 at 05:42
  • You can do it like this ```outputImage = np.uint8(np.zeros(image.shape[:2])) outputImage[np.where(labels == 1)] = 255 cv2.imshow('output', outputImage)``` – Sanchit.Jain Oct 16 '19 at 06:07
  • Ahh! That's it! Much simpler than I thought! Thanks a lot for the help! – Yasin Oct 16 '19 at 06:13
0

You can use pointPolygonTest function to check whether a point is inside a contour or not.

So, after thresholding, find the contours in the image using findContours function. Then you can pass the contours and the point to this function to check whether the point is inside the region or not.

Since you have the connected components and stats (that you found using connectedComponentsWithStats), you can test faster using this approach.

Gopiraj
  • 647
  • 7
  • 19