如何查找和测量图像中的弧长(measure an arc)

需要一些帮助。我需要获取图像中标记的从 A 点到 B 点的弧长,单位为厘米。此外,我们需要在唯一的腿上提取图像中可能存在或可能不存在的任何其他内容。这是使用 Python 和 OpenCV。我已经能够从其中许多中只获得 2 个最大的轮廓,但努力只保留到最大的一个。下面给出的是当前代码。

需要一些帮助。我需要获取图像中标记的从 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

1

我假设脚将始终处于此方向(没有旋转,没有上下颠倒)。

要保持最大轮廓,您可以:

遍历轮廓并计算轮廓面积: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。

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

获得最大轮廓的索引的琐碎代码:

size_t id_max_area = 0;
double max_area = 0.0;
for(size_t i = 0; i < contours.size(); i++) {
    double area = cv::contourArea(contours[i]);
    if(max_area < area) {
        max_area = area;
        id_max_area = i;
    }
}

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

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);

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(261)
HTTP错误 500.32-将自包含.NetCore3.1应用程序部署到Azure后 ANCM无法加载dll
上一篇
如何在Wordpress中正确出列某些Elementorcss文件
下一篇

相关推荐

  • type c接口是啥改变你的充电体验

    示例示例Type C接口是一种新型的USB连接器,它可以支持更高的数据传输速度,比传统的USB 0接口更快。与传统的USB接口不同,Type C接口可以在两端都使用,无需额外的翻转,使连接更加方便快捷。下面是一个使用Type C接口的代码示例:…

    2023-01-12 02:06:09
    0 34 55
  • carwings是什么意思智能汽车连接系统的未来

    Carwings是日产汽车公司推出的一款远程智能汽车服务,它可以帮助用户远程监控汽车的状态和行驶信息,并且可以远程控制汽车的功能。…

    2023-01-19 13:55:38
    0 42 69
  • cvt变速箱油分几种:CVT变速箱油的种类及用法

    cvt变速箱油一般分为三种,分别是:传统cvt变速箱油:代码:CVT-1…

    2023-01-27 12:23:25
    0 58 15
  • cv人生履历:从零开始,一步步走向成功——[姓名]的职业生涯

    cv人生履历是一种概括性的文件,用于描述一个人的教育背景、工作经历、技能、专业知识和其他重要信息的文件。它可以帮助雇主评估求职者的资格,并决定是否面试或录用他们。…

    2023-02-01 13:25:09
    0 68 39
  • contextcapture集群:如何使用ContextCapture技术构建高效的3D集群

    ContextCapture集群是一种分布式的技术,它可以让多台服务器共享数据,从而提高应用程序的性能和可靠性。它可以使用多台服务器来收集、存储和处理数据,而不需要单独的服务器来执行这些任务。…

    2023-01-05 08:03:52
    0 38 86
  • cdb文件解锁您的数据库

    CDB文件是一种关联数据库文件格式,用于存储结构化的键/值数据。它是一种高效的文件格式,可以快速检索和更新数据。它可以用作存储用户配置文件,字典,索引,缓存等。…

    2023-02-04 07:44:32
    0 79 86
  • code128条码字体下载:使用 Code128 条码字体创建条码标识

    code128条码字体下载是指下载code128条码字体的过程。Code128条码字体是一种用于生成Code128条形码的字体。它可以将文本转换为条形码,并将条形码打印在各种类型的媒体上。要下载code128条码字体,可以从网上搜索“code128条码字体下载”,然后选择一个可靠的网站下载。一旦下载完成,就可以使用该字体创建code128条形码。…

    2023-01-19 14:44:33
    0 11 15
  • txvlog com糖心改变你的生活,让你的心情更加甜蜜!

    txvlog com糖心是一款以视频分享为主的社交APP,可以让用户上传自己的视频,并与其他用户进行互动。它的主要功能有:用户注册:用户可以通过手机号码、邮箱地址或者社交媒体账号注册,并设置自己的个人信息;…

    2023-01-10 05:08:15
    0 82 17

发表评论

登录 后才能评论

评论列表(75条)