首页 > 解决方案 > 找到凹弯曲形状斑点的宽度和高度

问题描述

我一直在为计算像这样的图形的宽度和高度测量值这个问题而摸不着头脑。主要的挑战是我不能使用 miBoundingrectangle 并且无法从内部找出一种边界方法,无论哪种方式,我都会丢失一些用于高度和宽度测量的像素。

样本输入:

在此处输入图像描述

样本输出:

在此处输入图像描述

是否有任何防故障方法来获得准确的尺寸测量?

下面是我试图找到内部边界最大矩形的解决方案。

_,contour2,_=cv2.findContours(im,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
for c in contour2:
    area=cv2.contourArea(c)
    if area ==25224.0:
        print(area)
        n = np.squeeze(contour2[0])

        x = sorted(n, key=lambda a:a[0])
        left = x[0]
        right = x[-1]
        print("",left,right)
        y= sorted(n, key=lambda a:a[1])
        top = y[0]
        bottom = y[-1]
        cv2.drawContours(im,[c],-1,(128,128,128),2)
        cv2.circle(im, (left[0],left[1]), 4, (128,128,128), 8)
        cv2.circle(im, (right[0],right[1]), 4, (128,128,128), 8)
        cv2.circle(im, (top[0],top[1]), 4, (128,128,128), 8)
        cv2.circle(im, (bottom[0],bottom[1]), 4, (128,128,128), 8)

        roi_w = int(np.sqrt((top[0]-right[0])*(top[0]-right[0])(top[1]-right[1])*(top[1]-right[1])))
        roi_h = int(np.sqrt((top[0]-left[0])*(top[0]-left[0])+(top[1]-left[1])*(top[1]-left[1])))
                pts1 = np.float32([top,right,left])

        new_top = top
        new_right = [top[0] + roi_w, top[1]]
        new_left = [top[0], top[1] + roi_h]
        pts2 = np.float32([new_top,new_right,new_left])

     cv2.imshow("threshed", im)`

标签: pythonimageopencvimage-processingcomputer-vision

解决方案


这是一个 OpenCV 解决方案。主要思想是

  • 将图像转换为灰度和反转图像
  • 查找 blob 的轮廓和质心
  • 使用 Numpy 切片获取所有行/列像素
  • 计算非零像素以确定宽度/高度

我们将图像转换为灰度并反转它。这是我们将计算像素的图像,因为所需的 ROI 是白色的。从这里,我们使用 找到斑点的轮廓和中心坐标cv2.moments()。这给了我们质心(即对象的中心 (x, y) 坐标)

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

接下来我们使用 Numpy 切片来获取所有的行和列像素。我们使用cv2.countNonZero()这样来查找行/列的宽度/高度

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

这是一个可视化

在此处输入图像描述

这是结果

第 150 行

第 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] if len(cnts) == 2 else 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)

推荐阅读