gpt4 book ai didi

python - 如何计算图像中不规则对象的面积(opencv-Python 3.8)?

转载 作者:行者123 更新时间:2023-12-02 17:16:45 26 4
gpt4 key购买 nike

所以我有这个形象:
enter image description here
而且我需要计算特定零件的面积,所以我编写了以下代码:

# packages
from imutils import perspective
from imutils import contours
import numpy as np
import imutils
import cv2

image = cv2.imread('image1.jpg')

# load the image, convert it to grayscale, and blur it slightly
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0)
edged = cv2.Canny(gray, 80, 150)
edged = cv2.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)
# find contours
cnts = cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
# sort the contours from left-to-right and initialize the
(cnts, _) = contours.sort_contours(cnts)
pixelsPerMetric = None
# draw the necessary contour
cv2.drawContours(image, max(cnts, key=cv2.contourArea), -1, (0, 0, 255), 5)
cv2.imshow("Image", image)
cv2.waitKey(0)
我得到了这张图片:
enter image description here
我想用红色轮廓线测量面积(mm²)。作为参考,我有硬币(572.55毫米)和其他问题。是否可以测量红色轮廓中的红色和黑色比例。一些建议。

最佳答案

再见,
我会这样。本质上:

  • 在第一部分中,您将研究外部轮廓:您将找到硬币和 slice 的外部边界

  • external borders
  • 硬币面积将帮助您测量整个 slice 的以cm ^ 2为单位的面积,如果要以mm ^ 2为单位,则可以将该值乘以100
  • 此时,您只需要量化 slice 的精益部分,这是受this great snippetfmw42
  • 上方的出色评论的启发

    lean selection
  • 可以通过差异找到 slice 的脂肪部分,即,根据我的值,我可以看到 slice 的57.71%是lean,所以剩下的42.29%是脂肪
  • 如果您不希望像此代码段中那样整个精瘦部分只是计算红色轮廓的面积,则您似乎已经准备好:切记 slice 比我在这里计算的要胖

  • 事不宜迟,这里是代码:
    import cv2
    import numpy as np
    import math

    # input image
    path = "image1.jpg"
    # 1 EUR coin diameter in cm
    coinDiameter = 2.325
    # real area for the coin in cm^2
    coinArea = (coinDiameter/2)**2 * math.pi
    # initializing the multiplying factor for real size
    realAreaPerPixel = 1


    # pixel to cm^2
    def pixelToArea(objectSizeInPixel, coinSizeInPixel):
    # how many cm^2 per pixel?
    realAreaPerPixel = coinArea / coinSizeInPixel
    print("realAreaPerPixel: ", realAreaPerPixel)
    # object area in cm^2
    objectArea = realAreaPerPixel * objectSizeInPixel
    return objectArea


    # finding coin and steak contours
    def getContours(img, imgContour):

    # find all the contours from the B&W image
    contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # needed to filter only our contours of interest
    finalContours = []

    # for each contour found
    for cnt in contours:
    # cv2.drawContours(imgContour, cnt, -1, (255, 0, 255), 2)
    # find its area in pixel
    area = cv2.contourArea(cnt)
    print("Detected Contour with Area: ", area)

    # minimum area value is to be fixed as the one that leaves the coin as the small object on the scene
    if (area > 5000):
    perimeter = cv2.arcLength(cnt, True)

    # smaller epsilon -> more vertices detected [= more precision]
    epsilon = 0.002*perimeter
    # check how many vertices
    approx = cv2.approxPolyDP(cnt, epsilon, True)
    #print(len(approx))

    finalContours.append([len(approx), area, approx, cnt])

    # we want only two objects here: the coin and the meat slice
    print("---\nFinal number of External Contours: ", len(finalContours))
    # so at this point finalContours should have only two elements
    # sorting in ascending order depending on the area
    finalContours = sorted(finalContours, key = lambda x:x[1], reverse=False)

    # drawing contours for the final objects
    for con in finalContours:
    cv2.drawContours(imgContour, con[3], -1, (0, 0, 255), 3)

    return imgContour, finalContours


    # sourcing the input image
    img = cv2.imread(path)
    cv2.imshow("Starting image", img)
    cv2.waitKey()

    # blurring
    imgBlur = cv2.GaussianBlur(img, (7, 7), 1)
    # graying
    imgGray = cv2.cvtColor(imgBlur, cv2.COLOR_BGR2GRAY)
    # canny
    imgCanny = cv2.Canny(imgGray, 255, 195)

    kernel = np.ones((2, 2))
    imgDil = cv2.dilate(imgCanny, kernel, iterations = 3)
    # cv2.imshow("Diluted", imgDil)
    imgThre = cv2.erode(imgDil, kernel, iterations = 3)

    imgFinalContours, finalContours = getContours(imgThre, img)

    # first final contour has the area of the coin in pixel
    coinPixelArea = finalContours[0][1]
    print("Coin Area in pixel", coinPixelArea)
    # second final contour has the area of the meat slice in pixel
    slicePixelArea = finalContours[1][1]
    print("Entire Slice Area in pixel", slicePixelArea)

    # let's go cm^2
    print("Coin Area in cm^2:", coinArea)
    print("Entire Slice Area in cm^2:", pixelToArea(slicePixelArea, coinPixelArea))

    # show the contours on the unfiltered starting image
    cv2.imshow("Final External Contours", imgFinalContours)
    cv2.waitKey()


    # now let's detect and quantify the lean part

    # convert to HSV
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    # set lower and upper color limits
    lowerVal = np.array([0, 159, 160])
    upperVal = np.array([101, 255, 253])
    # Threshold the HSV image to get only red colors
    mask = cv2.inRange(hsv, lowerVal, upperVal)
    # apply mask to original image - this shows the red with black blackground
    final = cv2.bitwise_and(img, img, mask= mask)

    # show selection
    cv2.imshow("Lean Cut", final)
    cv2.waitKey()

    # convert it to grayscale because countNonZero() wants 1 channel images
    gray = cv2.cvtColor(final, cv2.COLOR_BGR2GRAY)
    # cv2.imshow("Gray", gray)
    # cv2.waitKey()
    meatyPixelArea = cv2.countNonZero(gray)

    print("Red Area in pixel: ", meatyPixelArea)
    print("Red Area in cm^2: ", pixelToArea(meatyPixelArea, coinPixelArea))

    # finally the body-fat ratio calculation
    print("Body-Fat Ratio: ", meatyPixelArea/slicePixelArea*100, "%")

    cv2.destroyAllWindows()
    周末愉快,
    安东诺

    关于python - 如何计算图像中不规则对象的面积(opencv-Python 3.8)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64394768/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com