gpt4 book ai didi

python - 使用 Python/OpenCV 从图像中提取固定数量的正方形

转载 作者:太空宇宙 更新时间:2023-11-03 22:17:43 24 4
gpt4 key购买 nike

我有几个扫描图像,我想用 Python/Opencv 计算。这些图像中的每一个(参见下面的示例)都包含 n 行彩色方 block 。这些正方形中的每一个都具有相同的大小。目标是裁剪每个方 block 并从中提取数据。

Image with squares to extract

我找到了 there能够从图像中提取正方形的代码。

这是我使用过的代码:

import numpy as np
import cv2
from matplotlib import pyplot as plt

def angle_cos(p0, p1, p2):
import numpy as np

d1, d2 = (p0-p1).astype('float'), (p2-p1).astype('float')
return abs( np.dot(d1, d2) / np.sqrt( np.dot(d1, d1)*np.dot(d2, d2) ) )

def find_squares(img):
import cv2 as cv
import numpy as np

img = cv.GaussianBlur(img, (5, 5), 0)
squares = []
for gray in cv.split(img):
for thrs in range(0, 255, 26):
if thrs == 0:
bin = cv.Canny(gray, 0, 50, apertureSize=5)
bin = cv.dilate(bin, None)
else:
_retval, bin = cv.threshold(gray, thrs, 255, cv.THRESH_BINARY)
contours, _hierarchy = cv.findContours(bin, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
for cnt in contours:
cnt_len = cv.arcLength(cnt, True)
cnt = cv.approxPolyDP(cnt, 0.02*cnt_len, True)
if len(cnt) == 4 and cv.contourArea(cnt) > 1000 and cv.isContourConvex(cnt):
cnt = cnt.reshape(-1, 2)
max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in range(4)])
if max_cos < 0.1:
squares.append(cnt)
print(len(squares))
return squares

img = cv2.imread("test_squares.jpg",1)

plt.axis("off")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()

squares = find_squares(img)
cv2.drawContours( img, squares, -1, (0, 255, 0), 1 )
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()

但是,它找到了两个正方形(100 个而不是 15 个!!)。从图像上看,似乎 Opencv 为每个正方形找到了很多轮廓。

我很确定它可以优化,因为正方形的大小大致相同并且彼此相距很远。作为 Opencv 的初学者,我还没有找到一种方法来在函数“查找正方形”中提供更多标准,以便在例程结束时只得到 15 个正方形。也许轮廓区域可以最大化?

我还找到了there更详细的代码(非常接近上一个)但它似乎是在旧版本的 Opencv 中开发的。我还没有设法让它工作(因此无法修改它)。

最佳答案

这是 another more robust method .

我使用这段代码来查找图像中的轮廓(完整代码可以在 in this gist 中找到):

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Define square size
min_square_size = 987
# Read Image
img = cv2.imread('/home/stephen/Desktop/3eY0k.jpg')
# Threshold and find edges
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Threshold the image - segment white background from post it notes
_, thresh = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY_INV);
# Find the contours
_, contours, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

我遍历了轮廓。我只看了尺寸合理的轮廓。我找到了每个轮廓的四个角。

corners

# Create a list for post-it images
images = []
# Iterate through the contours in the image
for contour in contours:
area = cv2.contourArea(contour)
# If the contour is not really small, or really big
h,w = img.shape[0], img.shape[1]
if area > min_square_size and area < h*w-(2*(h+w)):
# Get the four corners of the contour
epsilon = .1 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
# Draw the point
for point in approx: cv2.circle(img, tuple(point[0]), 2, (255,0,0), 2)
# Warp it to a square
pts1 = np.float32(approx)
pts2 = np.float32([[0,0],[300,0],[300,300],[0,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(300,300))
# Add the square to the list of images
images.append(dst.copy())

便利贴是正方形,但由于相机扭曲了图像中的对象,因此它们不会显示为正方形。我使用 warpPerspective 将便利贴制作成方形。此图中仅显示了其中的几个(还有更多不适合): plot

关于python - 使用 Python/OpenCV 从图像中提取固定数量的正方形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55832414/

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