gpt4 book ai didi

Python:使用 OpenCV 从左上到右下对项目进行排序

转载 作者:行者123 更新时间:2023-12-03 15:53:35 26 4
gpt4 key购买 nike

我如何尝试从左上角到右下角对图片的项目进行排序,如下图所示?当前使用以下代码收到此错误。
错误:

a = sorted(keypoints, key=lambda p: (p[0]) + (p1))[0] # find upper left pointValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()


这个问题是从这个建模的: Ordering coordinates from top left to bottom right
def preprocess(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_blur = cv2.GaussianBlur(img_gray, (5, 5), 1)
img_canny = cv2.Canny(img_blur, 50, 50)
kernel = np.ones((3, 3))
img_dilate = cv2.dilate(img_canny, kernel, iterations=2)
img_erode = cv2.erode(img_dilate, kernel, iterations=1)
return img_erode

image_final = preprocess(picture_example.png)
keypoints, hierarchy = cv2.findContours(image_final, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
points = []

while len(keypoints) > 0:
a = sorted(keypoints, key=lambda p: (p[0]) + (p[1]))[0] # find upper left point
b = sorted(keypoints, key=lambda p: (p[0]) - (p[1]))[-1] # find upper right point

cv2.line(image_final, (int(a.pt[0]), int(a.pt[1])), (int(b.pt[0]), int(b.pt[1])), (255, 0, 0), 1)

# convert opencv keypoint to numpy 3d point
a = np.array([a.pt[0], a.pt[1], 0])
b = np.array([b.pt[0], b.pt[1], 0])

row_points = []
remaining_points = []
for k in keypoints:
p = np.array([k.pt[0], k.pt[1], 0])
d = k.size # diameter of the keypoint (might be a theshold)
dist = np.linalg.norm(np.cross(np.subtract(p, a), np.subtract(b, a))) / np.linalg.norm(b) # distance between keypoint and line a->b
if d/2 > dist:
row_points.append(k)
else:
remaining_points.append(k)

points.extend(sorted(row_points, key=lambda h: h.pt[0]))
keypoints= remaining_points
新图:
enter image description here
引用订购图片:
enter image description here
将使用质心来确定中心点顺序。

最佳答案

结果编号取决于您希望有多少行。通过我将向您展示如何制作的程序,您可以在运行程序之前指定行数。
例如,这是原始图像:
enter image description here
这是指定 4 行时的编号图像:
enter image description here
这是指定 6 行时的编号图像:
enter image description here
对于您提供的其他图像(其框架被裁剪,因此框架不会被检测为形状),您可以看到将有 4 行,因此将 4 放入程序将为您提供:
enter image description here

让我们看一下考虑 4 行的工作流程。我使用的概念是将图像沿 y 轴分成 4 段,形成 4 行。对于图像的每个片段,找到其中心在该片段中的每个形状。最后,按 x 坐标对每个线段中的形状进行排序。

  • 导入必要的库:
  • import cv2
    import numpy as np
  • 定义一个函数,该函数将接收图像输入并将处理后的图像返回到允许 python 稍后检索其轮廓的东西:
  • def process_img(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_canny = cv2.Canny(img_gray, 100, 100)
    kernel = np.ones((2, 3))
    img_dilate = cv2.dilate(img_canny, kernel, iterations=1)
    img_erode = cv2.erode(img_dilate, kernel, iterations=1)
    return img_erode
  • 定义一个返回轮廓中心的函数:
  • def get_centeroid(cnt):
    length = len(cnt)
    sum_x = np.sum(cnt[..., 0])
    sum_y = np.sum(cnt[..., 1])
    return int(sum_x / length), int(sum_y / length)
  • 定义一个函数,该函数将接收处理过的图像并返回图像中找到的形状的中心点:
  • def get_centers(img):
    contours, hierarchies = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    for cnt in contours:
    if cv2.contourArea(cnt) > 100:
    yield get_centeroid(cnt)
  • 定义一个接收图像数组的函数,img , 坐标数组, centers ,图像的段数,row_amt ,以及每段的高度,row_h ,作为输入。它将返回 row_amt数组(按其 x 坐标排序),每个数组包含 centers 中的每个点位于图像的相应行中:
  • def get_rows(img, centers, row_amt, row_h):
    centers = np.array(centers)
    d = row_h / row_amt
    for i in range(row_amt):
    f = centers[:, 1] - d * i
    a = centers[(f < d) & (f > 0)]
    yield a[a.argsort(0)[:, 0]]
  • 读入图像,使用 processed 获取其处理形式函数定义,并使用 centers 获取图像中每个形状的中心函数定义:
  • img = cv2.imread("shapes.png")
    img_processed = process_img(img)
    centers = list(get_centers(img_processed))
  • 获取图像的高度以用于 get_rows函数定义,并定义一个计数变量,count , 跟踪编号:
  • h, w, c = img.shape
    count = 0
  • 循环通过分成 4 行的形状的中心,绘制连接行的线以进行可视化:
  • for row in get_rows(img, centers, 4, h):
    cv2.polylines(img, [row], False, (255, 0, 255), 2)
    for x, y in row:
  • 添加到 count变量,并绘制 countrow 到图像上的特定位置数组:
  •         count += 1
    cv2.circle(img, (x, y), 10, (0, 0, 255), -1)
    cv2.putText(img, str(count), (x - 10, y + 5), 1, cv2.FONT_HERSHEY_PLAIN, (0, 255, 255), 2)
  • 最后,显示图像:
  • cv2.imshow("Ordered", img)
    cv2.waitKey(0)

    共:
    import cv2
    import numpy as np

    def process_img(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_canny = cv2.Canny(img_gray, 100, 100)
    kernel = np.ones((2, 3))
    img_dilate = cv2.dilate(img_canny, kernel, iterations=1)
    img_erode = cv2.erode(img_dilate, kernel, iterations=1)
    return img_erode

    def get_centeroid(cnt):
    length = len(cnt)
    sum_x = np.sum(cnt[..., 0])
    sum_y = np.sum(cnt[..., 1])
    return int(sum_x / length), int(sum_y / length)

    def get_centers(img):
    contours, hierarchies = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    for cnt in contours:
    if cv2.contourArea(cnt) > 100:
    yield get_centeroid(cnt)

    def get_rows(img, centers, row_amt, row_h):
    centers = np.array(centers)
    d = row_h / row_amt
    for i in range(row_amt):
    f = centers[:, 1] - d * i
    a = centers[(f < d) & (f > 0)]
    yield a[a.argsort(0)[:, 0]]

    img = cv2.imread("shapes.png")
    img_processed = process_img(img)
    centers = list(get_centers(img_processed))

    h, w, c = img.shape
    count = 0

    for row in get_rows(img, centers, 4, h):
    cv2.polylines(img, [row], False, (255, 0, 255), 2)
    for x, y in row:
    count += 1
    cv2.circle(img, (x, y), 10, (0, 0, 255), -1)
    cv2.putText(img, str(count), (x - 10, y + 5), 1, cv2.FONT_HERSHEY_PLAIN, (0, 255, 255), 2)

    cv2.imshow("Ordered", img)
    cv2.waitKey(0)

    关于Python:使用 OpenCV 从左上到右下对项目进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66946804/

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