最簡單-使用findContours
OpenCV 中有一個名為 findContours 的函數,可以用來查找圖像中的輪廓。一旦你找到了圖像中的輪廓,你可以使用 approxPolyDP 函數來近似地計算輪廓的形狀。如果你要查找正方形,你可以在這些形狀中尋找具有 4 個頂點的多邊形,這些多邊形應該有相近的邊長和角度。如果你要檢測的正方形不是水平的或垂直的,你可能需要使用角度信息來確定它的方向。
import cv2
# 读入图像
img = cv2.imread('square.jpg')
# 将图像转为灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用 Canny 边缘检测
edges = cv2.Canny(gray, 50, 150)
# 寻找轮廓
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 遍历轮廓
for contour in contours:
# 近似计算轮廓
approx = cv2.approxPolyDP(contour, 0.01 * cv2.arcLength(contour, True), True)
# 如果是 4 个顶点的多边形,且边长和角度相近,则认为是正方形
if len(approx) == 4 and cv2.isContourConvex(app
當我們可以取得相黏物件邊緣時 – 分水嶺演算法

當形狀邊緣不清楚時-使用霍夫找線
使用霍夫變換檢測直線。因為正方形的四條邊是直線,因此可以通過檢測這四條直線來確定正方形。
具體來說,可以使用 OpenCV 中的 HoughLinesP 函數來檢測直線。該函數會返回一組檢測到的線段,這些線段可以是任意方向和長度的線段,因此我們需要對這些線段進行篩選,只保留長度、方向和相對位置都符合要求的線段。接著,我們可以將這些線段按照一定的規則組合成四條邊,從而確定正方形。
以下是一個示例代碼,演示如何使用霍夫變換檢測正方形:
import cv2
import numpy as np
# 读入图像
img = cv2.imread('square.jpg')
# 将图像转为灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用 Canny 边缘检测
edges = cv2.Canny(gray, 50, 150)
# 使用霍夫变换检测直线
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=100, maxLineGap=10)
# 筛选直线
filtered_lines = []
for line in lines:
x1, y1, x2, y2 = line[0]
length = np.sqrt((x2-x1)**2 + (y2-y1)**2)
angle = np.arctan2(y2-y1, x2-x1)
# 保留长度在一定范围内的直线
if 100 < length < 200:
filtered_lines.append((length, angle, line))
# 组合直线
sides = []
for i, (length1, angle1, line1) in enumerate(filtered_lines):
for j, (length2, angle2, line2) in enumerate(filtered_lines[i+1:], i+1):
angle_diff = np.abs(angle1 - angle2)
# 保留角度相近的直线
if angle_diff < np.pi/4:
# 计算两条直线的中心点
x1, y1, x2, y2 = line1
cx1, cy1 = (x1+x2)/2, (y1+y2)/2
x1, y1, x2, y2 = line2
cx2, cy2 = (x1+x2)/2, (y1+y2)/2
center_diff = np.sqrt((cx2-cx1)**2 + (cy2-cy1)**2)
# 保留中心点距离相近的直线
if center_diff < 20:
# 将两条直线组合成一条边
sides.append((length1+length2, angle1, angle2, line1, line2))
# 按照长度排序,取前四条直线作为正方形的四条边
sides = sorted(sides
取前四条直线作为正方形的四条边
sides = sorted(sides, reverse=True)[:4]
计算正方形的四个顶点
corners = []
for i, (length1, angle1, angle2, line1, line2) in enumerate(sides):
for j, (length3, angle3, angle4, line3, line4) in enumerate(sides[i+1:], i+1):
# 计算两条直线的交点
x1, y1, x2, y2 = line1
cx1, cy1 = (x1+x2)/2, (y1+y2)/2
x1, y1, x2, y2 = line3
cx2, cy2 = (x1+x2)/2, (y1+y2)/2
k1 = np.tan(angle1)
k2 = np.tan(angle3)
x = (cy1 - cy2 + k2cx2 - k1cx1) / (k2 - k1)
y = k1*(x - cx1) + cy1
corners.append((x, y))
绘制正方形
for i in range(4):
x1, y1 = corners[i]
x2, y2 = corners[(i+1)%4]
cv2.line(img, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 3)
显示结果
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
基於角點的角點檢測
Harris Corner Detector 是一種角點檢測算子,常用於計算機視覺算法中以提取角點並推斷圖像的特徵。它由 Chris Harris 和 Mike Stephens 於 1988 年在 Moravec 的角檢測器改進後首次提出。Harris 角點檢測器相比之前的角點檢測器,直接考慮了角點分數的差異,直接參考方向,而不是每 45 度角使用 shifting patches,並被證明在區分邊緣和邊緣方面更準確。角落。從那以後,它被改進並被許多算法採用,為後續應用預處理圖像。

One Reply to “如何檢測畫面中可能的正方形”
Comments are closed.