【问题标题】:Fitting ellipse to random distributed uniform regular shapes将椭圆拟合到随机分布的均匀规则形状
【发布时间】:2021-10-20 21:58:14
【问题描述】:

我们可以将代表性图片中的形状想象成桌子上随机散落的铅笔或棍子。我一直试图通过拟合椭圆来找到每个形状的区域,但我无法正确拟合椭圆。你能帮助我吗?谢谢。

第一张图片是:输入图片

我尝试过的代码,

import cv2
import numpy as np
import random as rng
import math

img = cv2.imread('sticks.png', 1)
imge= cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
gray = cv2.cvtColor(imge, cv2.COLOR_BGR2GRAY)
blur = cv2.blur(gray, (2,2), 3)


rng.seed(1)
def thresh_callback(val):
threshold = val

canny_output = cv2.Canny(blur, threshold, threshold * 4)


contours, _ = cv2.findContours(canny_output, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
minRect = [None]*len(contours)
minEllipse = [None]*len(contours)
for i, c in enumerate(contours):
    minRect[i] = cv2.minAreaRect(c)
    if c.shape[0] > 5:
        minEllipse[i] = cv2.fitEllipse(c)
        (x,y),(minor_axis,major_axis),angle = minEllipse[i]
        half_major= major_axis/2
        half_minor= minor_axis/2
        pixel= 37.795275591
        half_major1= half_major/pixel
        half_minor1= half_minor/pixel
        area= math.pi * half_major1 * half_major1
        print(area)
        drawing = np.zeros((canny_output.shape[1], canny_output.shape[1], 3), dtype=np.uint8)

for i, c in enumerate(contours):
    color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
    cv2.drawContours(drawing, contours, i, color)
    if c.shape[0] > 5:
        cv2.ellipse(drawing, minEllipse[i], color, 1)
    


cv2.imshow('Fitting Ellips', drawing)


source_window = 'Source'
cv2.namedWindow(source_window)
cv2.imshow(source_window, img)
max_thresh = 255
thresh = 100
cv2.createTrackbar('Canny Thresh:', source_window,thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv2.waitKey()

第二张图是:预期结果(像这样拟合椭圆每一行)

【问题讨论】:

  • 为什么您删除了问题并重新创建完全相同的问题? :)
  • @Shamshirsaz.Navid 感谢您的关注,因为我之前的问题没有答案,我需要一个答案。感谢您的关注。

标签: python opencv image-processing image-segmentation


【解决方案1】:

这不是最终结果,肯定有错误。您需要花时间来达到预期的效果。但从以下开始可能是个好主意:

import sys
import cv2
import math
import numpy as np

# Check it there is a black area in specific position of an image
def checkPointArea(im, pt):
    x, y = pt[0], pt[1]
    return im[y, x, 0] == 0 or im[y, x+1, 0] == 0 or im[y, x-1, 0] == 0 or im[y+1, x, 0] == 0 or im[y-1, x, 0] == 0


# Load image
pth = sys.path[0]
im = cv2.imread(pth+'/im.jpg')
H, W = im.shape[:2]


# Make grayscale and black and white versions
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
bw = cv2.threshold(im, 110, 255, cv2.THRESH_BINARY)[1]

# Try to clear the parts of the image that are stuck together
bw = cv2.dilate(bw, np.ones((5, 5), np.uint8))

# Convert im back to BGR
im = cv2.cvtColor(im, cv2.COLOR_GRAY2BGR)

# Make some copies
org = im.copy()
empty = im.copy()
empty[:] = 255


# Find contours and sort them by position
cnts, _ = cv2.findContours(bw, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnts.sort(key=lambda x: cv2.boundingRect(x)[0])

# Thikness of random lines
thickness = 5

# Find and draw ellipses
for cnt in cnts:
    x, y, w, h = cv2.boundingRect(cnt)
    if w < W:
        cv2.rectangle(im, (x, y), (x+w, y+h), (10, 230, 0)
                      if w < h else (200, 0, 128), 1)
        hw, hh = w//2, h//2
        cx, cy = x+hw, y+hh

        r = int(math.sqrt(w**2+h**2))
        t, c = math.atan(hw/hh), (255, 0, 0)
        if checkPointArea(org, (x, y)) and checkPointArea(org, (x+w-1, y+h-1)):
            t, c = math.atan(hw/-hh), (100, 0, 200)
        deg = math.degrees(t)
        if w <= thickness*2:
            deg = 0
        if h <= thickness*2:
            deg = 90
        cv2.ellipse(im, (x, y), (1, 1), 0, 0, 360, c, 4)
        cv2.ellipse(im, (cx, cy), (thickness, r//2),
                    deg, 0, 360, (40, 0, 255), 2, lineType=cv2.LINE_AA)
        #cv2.ellipse(empty, (x, y), (1, 1), 0, 0, 360, c, 2)
        cv2.ellipse(empty, (cx, cy), (thickness, r//2),
                    deg, 0, 360, c, 2, lineType=cv2.LINE_AA)

# Save output
bw = cv2.cvtColor(bw, cv2.COLOR_GRAY2BGR)
top = np.hstack((org, empty))
btm = np.hstack((bw, im))
cv2.imwrite(pth+'/im_.png', np.vstack((top, btm)))

每个部分:

最终结果:

错误:
这两个部分你必须花更多的时间,第一个是由于我的代码薄弱。有更多时间可拆卸。二是由于两条线的重叠。清除图像对这部分没有帮助。您也许可以防止以后发生此类干扰。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多