Skip to content Skip to sidebar Skip to footer

Finding Width And Height Of Concave Curved Shaped Blob

I have been scratching my head over this problem of calculating the width and height measurements of a figure like this. The major challenge is I cant use miBoundingrectangle and c

Solution 1:

Here's an OpenCV solution. The main idea is

  • Convert image to grayscale and invert image
  • Find contour and centroid of the blob
  • Use Numpy slicing to grab all row/column pixels
  • Count non-zero pixels to determine width/height

We convert the image to grayscale and invert it. This is the image we will count pixels on since the desired ROI is in white. From here, we find the contour of the blob and the center coordinates using cv2.moments(). This gives us the centroid (i.e., the center (x, y)-coordinates of the object)

M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])

Next we use Numpy slicing to obtain all the row and column pixels. We use cv2.countNonZero() to find the width/height of the row/column like this

row_pixels = cv2.countNonZero(gray[cY][:])
column_pixels = cv2.countNonZero(gray[:, cX])

Here's a visualization

enter image description here

Here's the result

row 150

column 354

import cv2
import numpy as np

image = cv2.imread('1.png')
inverted = 255 - image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = 255 - gray

cnts = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] iflen(cnts) == 2else cnts[1]

for c in cnts:
    M = cv2.moments(c)
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])

    cv2.circle(inverted, (cX, cY), 5, (36, 255, 12), -1)
    inverted[cY][:] = (36, 255, 12)
    inverted[:, cX] = (36, 255, 12)
    row_pixels = cv2.countNonZero(gray[cY][:])
    column_pixels = cv2.countNonZero(gray[:, cX])

print('row', row_pixels)
print('column', column_pixels)
cv2.imshow('inverted', inverted)
cv2.imwrite('inverted.png', image)
cv2.waitKey(0)

Solution 2:

This is an Imagemagick solution. But the concept will give you a clue how to proceed with OpenCV. It is not quite the dimensions you want. But the closest way I could conceive. Basically, it is the maximum inside bounding box. Perhaps there is something similar in OpenCV.

Iterate around each edge of the image from outside towards the inside until each remaining edge is fully black with no white (or reasonably close to that).

Input:

enter image description here

convert img.png -threshold 0-define trim:percent-background=0%-trim +repage -format "%wx%h" +write info: result.png

returns: widthxheight =>144x317

enter image description here

ADDITION:

Here is another solution that should be easy to do in OpenCV.

Trim to get the minimum outer bounding box. Extract the center row and column, which may have some white on the ends. Then pad with white all around. Then trim all the white again so you have one black row and column remaining with no white. Then get the dimensions of the single black row and single black column.

width=`convert img.png -threshold 0 -trim +repage -gravity center -crop x1+0+0 +repage -bordercolor white -border 1x1 -trim +repage -format "%w" info:`
height=`convert img.png -threshold 0 -trim +repage -gravity center -crop 1x+0+0 +repage -bordercolor white -border 1x1 -trim +repage -format "%h" info:`
echo"width=$width; height=$height;"
returns: => width=145; height=352;

Post a Comment for "Finding Width And Height Of Concave Curved Shaped Blob"