最簡單-使用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,並被證明在區分邊緣和邊緣方面更準確。角落。從那以後,它被改進並被許多算法採用,為後續應用預處理圖像。