如何找到和测量图像中的弧长

2024-06-23 19:51:08 发布

您现在位置:Python中文网/ 问答频道 /正文

需要帮助。我需要得到从A点到B点的弧长,以厘米为单位,如图中所示。另外,我们需要在唯一的一条腿上提取图像中可能存在或不存在的其他内容。这是使用Python和OpenCV。我只能从他们中得到2个最大的轮廓,但努力保持最大的一个。下面给出的是当前代码。在

# import the necessary packages
from __future__ import print_function
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from scipy import ndimage
import numpy as np
import imutils
import cv2

image_dir = "/home/rahul/Desktop/img-708/"

img = cv2.imread(image_dir+'side_left.jpg')

lower = np.array([0, 48, 80], dtype = "uint8")
upper = np.array([20, 255, 255], dtype = "uint8")

# keep looping over the frames in the video


# resize the frame, convert it to the HSV color space,
# and determine the HSV pixel intensities that fall into
# the speicifed upper and lower boundaries
frame = imutils.resize(img, width = 400)
converted = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
skinMask = cv2.inRange(converted, lower, upper)

# apply a series of erosions and dilations to the mask
# using an elliptical kernel
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11))
skinMask = cv2.erode(skinMask, kernel, iterations = 2)
skinMask = cv2.dilate(skinMask, kernel, iterations = 2)

# blur the mask to help remove noise, then apply the
# mask to the frame
skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
skin = cv2.bitwise_and(frame, frame, mask = skinMask)

# show the skin in the image along with the mask
cv2.imwrite(image_dir+'output.jpg', np.hstack([skin]))

#image = cv2.imshow(np.hstack([skin])
image_dir = "/home/rahul/Desktop/img-708/"

image = cv2.imread(image_dir+'output.jpg')
#image = cv2.imread(pass)
shifted = cv2.pyrMeanShiftFiltering(image, 21, 51)
cv2.imshow("Input", image)

# convert the mean shift image to grayscale, then apply
# Otsu's thresholding
gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255,
    cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("Thresh", thresh)

# find contours in the thresholded image
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)[-2]
print("[INFO] {} unique contours found".format(len(cnts)))

# loop over the contours
for (i, c) in enumerate(cnts):
    # draw the contour
    ((x, y), _) = cv2.minEnclosingCircle(c)
    cv2.putText(image, "#{}".format(i), (int(x) - 10, int(y)),
        cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
    cv2.drawContours(image, [c], -1, (0, 255, 0), 2)

# show the output image
cv2.imshow("Image", image)
cv2.waitKey(0)

原始图像

enter image description here

我的代码的输出图像:

enter image description here


Tags: andthetoinfromimageimportimg
1条回答
网友
1楼 · 发布于 2024-06-23 19:51:08

我的脚永远不会朝下旋转。在

要保持最大轮廓,可以:

  • 迭代等高线并计算等高线面积:cv2.contourArea
  • 在等高线上画图,用:cv2.boundingRect得到边界矩形,以保持边界框面积最大的轮廓

使用cv2.boundingRect你可以同时得到边界矩形的宽度和脚的“全局”长度。在

如果需要弧长,一个可能的(也是更棘手的)解决方案是找到底部极值点,然后迭代轮廓点,并仅在这些极值点之间存储轮廓点。在

弧长可以用cv2.arcLength计算。在

带边框和极值点的图像结果:

enter image description here

带底部轮廓点的图像结果:

enter image description here

我得到了:

bounding rectangle width: 208 px
approximate arc length: 237.811 px

但是你必须记住,如果图像中没有校准对象,并且只有一个摄像头,你将无法以厘米为单位检索测量值,只能以像素为单位。在

<>编辑:按照要求,C++中的源代码,因为我没有Python,应该很容易翻译成Python。在

警告:可能无法处理更通用或其他数据的特定和琐碎代码。在

获取最大轮廓索引的简单代码:

^{pr2}$

获取极值点的(棘手的)代码:

cv::Point bottom_left(img.cols, 0), bottom_right(0, 0);
for(size_t i = 0; i < contours[id_max_area].size(); i++) {
    cv::Point contour_pt = contours[id_max_area][i];
    if(bottom_left.x > contour_pt.x)
        bottom_left.x = contour_pt.x;

    if(bottom_left.y < contour_pt.y)
        bottom_left.y = contour_pt.y;

    if(bottom_right.x < contour_pt.x)
        bottom_right.x = contour_pt.x;

    if(bottom_right.y < contour_pt.y)
        bottom_right.y = contour_pt.y;
}

保持底部轮廓点的代码(也很棘手):

std::vector<cv::Point> bottom_contour;
for(size_t i = 0; i < contours[id_max_area].size(); i++) {
    cv::Point contour_pt = contours[id_max_area][i];
    if(contour_pt.x >= bottom_left.x && contour_pt.x <= bottom_right.x
        && contour_pt.y > bottom_left.y - 15) {
        bottom_contour.push_back(contour_pt);
    }
}
double length = cv::arcLength(bottom_contour, false);

相关问题 更多 >

    热门问题