0

Just starting off with cv2, what i want is giving a seed to the object as in some window of coordinates and have him connected all the pixels that might be outside the initial box of coordinates but in contact with it. I started with small tests to get a feel of connected componenets:

im=cv2.imread('test.png', 0)
ret, thresh = cv2.threshold(im, 254, 255, cv2.THRESH_BINARY)
output = cv2.connectedComponentsWithStats(thresh, 4, cv2.CV_32S)

then

im=cv2.imread('test.png', 0)
ret, thresh = cv2.threshold(im, 254, 255, cv2.THRESH_BINARY)
thresh = cv2.bitwise_not(thresh)
output = cv2.connectedComponents(thresh, 4, cv2.CV_32S)

both of these outpute arrays, ok so far so good then i wanted to see the actual output image referring to the docs https://docs.opencv.org/3.0-beta/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#connectedcomponentsconnectedComponentsWithStats(InputArray image, OutputArray labels, OutputArray stats, OutputArray centroids, int connectivity=8, int ltype=CV_32S) and labels – destination labeled image so i changed the last line in the small code shared above to this:

output = cv2.connectedComponents(thresh,"out_test.png" ,4, cv2.CV_32S)

and it gave me the error shared in the question.i also tried:

cv2.imwrite(dest_dir+"out_test.png", output)

and got this error:

TypeError: img is not a numerical tuple

how can i actually visualize the output as i don't want to count the blobs(objects), their sizes or anything else i just want them to grow from the original region of interest i give.

Nelly
  • 81
  • 6

2 Answers2

1

If you want the white blobs to grow you can use Morphological Transformations

Do understand what the function does before using it

cv2.connectedComponents

Help on built-in function connectedComponents:

connectedComponents(...)
    connectedComponents(image[, labels[, connectivity[, ltype]]]) -> retval, labels
    .   @overload
    .   
    .   @param image the 8-bit single-channel image to be labeled
    .   @param labels destination labeled image
    .   @param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
    .   @param ltype output image label type. Currently CV_32S and CV_16U are supported

@ausk answer should be of use to you

import cv2

in terminal after you open python then

Example

help(cv2.connectedComponents)

Hope this helps

import cv2
import numpy as np
from matplotlib import pyplot as plt

image = cv2.imread("image.jpg")
grayscaleImage = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresholdedImage = np.zeros((image.shape[0],image.shape[1]),np.uint8)
thresholdedImage[grayscaleImage<250]=[255]

interestedObjects, interestedObjectContours, interestedObjectsHierarchy = cv2.findContours(thresholdedImage,cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)


for i, l in enumerate(interestedObjectContours):
    rect = cv2.minAreaRect(interestedObjectContours[i])
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    box[box < 0] = 0
    cv2.drawContours(image, [box], 0, (0, 255, 0), 2)


plt.subplot(111), plt.imshow(cv2.cvtColor(image,cv2.COLOR_BGR2RGB))
plt.title('Your objects detected image'), plt.xticks([]), plt.yticks([])
plt.show()
  • I want it to connect attached pixels, for example if i provide a completely blank image with a square somewhere n its middle, and if i give it the coordinates of a portion of the square it should find it all and grow to give the entire square as output, that's not what morphological transformations are for. – Nelly Jun 14 '18 at 07:26
  • Got it, if we have only the borders of a square on black image. You want the entire square to be turned into white pixels. Is it right? – Santhosh Dhaipule Chandrakanth Jun 14 '18 at 07:33
  • For my exact task there won't be only borders, the objects are filled and my task is basically having a part of black pixels(objects) on a white background, be able to make the "cropped" objects output their full size, what i'd give as input is the original full image and coordinates of the crop region, if you'd like to edit your answer to simulate a similar case i'd be thankful. – Nelly Jun 14 '18 at 07:37
  • To help you out, I want to know what the input will be `colour image` or `binary image`, I want to know your end goal. to suggest you a solution. – Santhosh Dhaipule Chandrakanth Jun 14 '18 at 07:45
  • Rgb image then i have to do the necessary modification if needed but kindly note the image is mostly black and white but still in rgb – Nelly Jun 14 '18 at 07:55
  • You can use `threshold` all the white background, then use `findcontour` [findContour](https://docs.opencv.org/3.1.0/d4/d73/tutorial_py_contours_begin.html) and then draw this contour using [Bounding Rectangle](https://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html) on the original image – Santhosh Dhaipule Chandrakanth Jun 14 '18 at 08:29
0
Help on built-in function connectedComponents:

connectedComponents(...)
    connectedComponents(image[, labels[, connectivity[, ltype]]]) -> retval, labels
    .   @overload
    .
    .   @param image the 8-bit single-channel image to be labeled
    .   @param labels destination labeled image
    .   @param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
    .   @param ltype output image label type. Currently CV_32S and CV_16U are supported.

import cv2 
fname = "test.png"
img=cv2.imread(fname, 0)
ret, thresh = cv2.threshold(img, 254, 255, cv2.THRESH_BINARY)
thresh = cv2.bitwise_not(thresh)
nums, labels = cv2.connectedComponents(thresh, None, 4, cv2.CV_32S)
dst = cv2.convertScaleAbs(255.0*labels/nums)
cv2.imwrite("dst.png", dst)
Kinght 金
  • 17,681
  • 4
  • 60
  • 74
  • Thanks for the answer, can you kindly explain a bit more for example what is it that i did wrong and what type of images can we apply connected components on(rgb , grayscale, binary...) as well as referring me to a more detailed explanation other than the docs cause they're pretty concise for a beginner. – Nelly Jun 14 '18 at 07:18