1

I want to use the function cv2.connectedComponents to connect components on a binary image, like the following...

image.

Everything works, except the outputted labels array. In this array are only zeros and not sequential numbers as indicated, according to the identified components.

import cv2
import numpy as np

img = cv2.imread('eGaIy.jpg', 0)
img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1]  # ensure binary
ret, labels = cv2.connectedComponents(img)

# Map component labels to hue val
label_hue = np.uint8(179*labels/np.max(labels))
blank_ch = 255*np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])

# cvt to BGR for display
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)

# set bg label to black
labeled_img[label_hue==0] = 0

cv2.imshow('labeled.png', labeled_img)
cv2.waitKey()

outputted labels --> labels.shape: (256L, 250L)

[[0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 ..., 
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]]
freddykrueger
  • 309
  • 4
  • 17
  • what is the value of ret? – api55 Jan 16 '18 at 11:57
  • ret is the number of detected components – freddykrueger Jan 16 '18 at 12:02
  • I know what it is, I was just wandering if it was giving you 1 (only background label) or a normal number. I will test it to see if i can reproduce the error – api55 Jan 16 '18 at 13:36
  • It gives me the white components, not the 1 background component...Do you know, why the array only contains zeros? – freddykrueger Jan 16 '18 at 13:38
  • I test it myself and it works, it gives me the same result as silencer, copy pasting your code.... if you print a numpy array you do not see all the values, where it has `...` means that you have a bunch of other values there. A simple test would be to do `np.sum(labels)` if it is 0 then it is only 0. Yo can try silencer suggestion for your test as well – api55 Jan 16 '18 at 13:44
  • A new "problem" occurs ... https://stackoverflow.com/questions/48303309/use-cv2-connectedcomponents-and-eliminate-elements-with-a-small-number-of-pixels – freddykrueger Jan 17 '18 at 14:22

1 Answers1

2

It works for me:

enter image description here enter image description here


And you should be careful that the function only find the component of nonzero. In the source image, the components are the edges. And the returned are labeled image as the same size of source.

The output of

[[0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 ..., 
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]]

only represent the 4 corner regions(3x3) are all zeros, but it doesn't mean all elements are zeros.


If you call this after you call the cv2.connectedComponents:

print(set(labels.reshape(-1).tolist()))

You will get:

{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}

It means there exist 14 components(edges), and 1 background(0).

Kinght 金
  • 17,681
  • 4
  • 60
  • 74
  • I already know that the algorithm works visually. I have saved the array: "labels" as .csv using the algorithm "numpy. savetxt" and it contains only zeros. Why? – freddykrueger Jan 16 '18 at 13:47
  • It's ok for me when `np.savetxt("t.txt", labels)`, contains all 0~14 in float.Check again on your machine. Notice, almost all are zeros, not all are zeros. – Kinght 金 Jan 16 '18 at 14:03
  • "Almost all are zeros, not all are zeros." ... You are right! Thanks! – freddykrueger Jan 16 '18 at 14:06
  • Something like that, `0.000000000000000000e+00 1.000000000000000000e+00 0.000000000000000000e+00`. Not easy to find non-zero, but why not search `1~9` in the txt? – Kinght 金 Jan 16 '18 at 14:10
  • A new "problem" occurs ... https://stackoverflow.com/questions/48303309/use-cv2-connectedcomponents-and-eliminate-elements-with-a-small-number-of-pixels – freddykrueger Jan 17 '18 at 14:22
  • @freddykrueger Done! https://stackoverflow.com/questions/48303309/use-cv2-connectedcomponents-and-eliminate-elements-with-a-small-number-of-pixels – Kinght 金 Jan 17 '18 at 14:46