mat*_*th5 5 python opencv image-processing python-3.x
我如何尝试从左上角到右下角对图片的项目进行排序,如下图所示?当前使用以下代码收到此错误。
错误:
a = sorted(keypoints, key=lambda p: (p[0]) + (p 1 ))[0] # 找到左上点 ValueError: 包含多个元素的数组的真值不明确。使用 a.any() 或 a.all()
这个问题是从这个建模的:Ordering坐标从左上角到右下角
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
Run Code Online (Sandbox Code Playgroud)
新图片:
参考订购图片:
将使用质心来确定中心点顺序。
结果编号取决于您希望有多少行。通过我将向您展示如何制作的程序,您可以在运行程序之前指定行数。
例如,这是原始图像:
这是指定 4 行时的编号图像:
这是指定 6 行时的编号图像:
对于您提供的其他图像(其框架被裁剪,因此框架不会被检测为形状),您可以看到将有 4 行,因此将 4 放入程序将为您提供:
让我们看一下考虑 4 行的工作流程。我使用的概念是将图像沿 y 轴分成 4 段,形成 4 行。对于图像的每个片段,找到其中心在该片段中的每个形状。最后,按 x 坐标对每个线段中的形状进行排序。
import cv2
import numpy as np
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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]]
Run Code Online (Sandbox Code Playgroud)
processed定义的函数获取其处理形式,并使用定义的函数获取图像中每个形状的中心centers:img = cv2.imread("shapes.png")
img_processed = process_img(img)
centers = list(get_centers(img_processed))
Run Code Online (Sandbox Code Playgroud)
get_rows定义函数的图像高度,并定义一个计数变量count,以跟踪编号:h, w, c = img.shape
count = 0
Run Code Online (Sandbox Code Playgroud)
for row in get_rows(img, centers, 4, h):
cv2.polylines(img, [row], False, (255, 0, 255), 2)
for x, y in row:
Run Code Online (Sandbox Code Playgroud)
count变量,并count从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)
Run Code Online (Sandbox Code Playgroud)
cv2.imshow("Ordered", img)
cv2.waitKey(0)
Run Code Online (Sandbox Code Playgroud)
共:
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
489 次 |
| 最近记录: |