1. 棋盘格角点检测与绘制
任务说明
本案例的目标是:读取一张棋盘格图像,使用OpenCV检测棋盘格的内角点(即黑白方格交界处的点),并将检测到的角点坐标以彩色圆点和连线的方式绘制在图像上,最终显示并保存结果图像。通过本案例,你将掌握cv2.findChessboardCorners与cv2.drawChessboardCorners的核心用法,为后续相机标定打下基础。
实现方案
我们使用OpenCV内置的棋盘格检测函数完成角点提取。核心步骤为:读取图像→转为灰度图→调用cv2.findChessboardCorners检测内角点→若检测成功则调用cv2.drawChessboardCorners在原图上绘制角点与连线→显示并保存结果。需要特别注意的是,棋盘格尺寸参数(w, h)指的是内角点数量,而非棋盘格方块数量。例如一个9×6的棋盘格,其内角点数为(8, 5)。
完整代码
import cv2
import numpy as np
# 棋盘格内角点尺寸(宽方向内角点数, 高方向内角点数)
# 例如:实际棋盘格为10×7格,则内角点为(9, 6)
pattern_size = (9, 6)
# 读取图像(请将图片路径替换为实际路径)
image_path = "chessboard.jpg"
img = cv2.imread(image_path)
if img is None:
print("错误:无法读取图像,请检查路径")
exit()
# 转为灰度图(检测算法需要单通道输入)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测棋盘格内角点
# flags=cv2.CALIB_CB_ADAPTIVE_THRESH 可增强不同光照下的检测鲁棒性
found, corners = cv2.findChessboardCorners(gray, pattern_size,
flags=cv2.CALIB_CB_ADAPTIVE_THRESH)
if found:
# 在原图上绘制检测到的角点(彩色圆点+连线)
img_with_corners = img.copy()
cv2.drawChessboardCorners(img_with_corners, pattern_size, corners, found)
# 显示结果
cv2.imshow("Chessboard Corners", img_with_corners)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存结果图像
output_path = "chessboard_corners_result.jpg"
cv2.imwrite(output_path, img_with_corners)
print(f"检测成功!共检测到 {len(corners)} 个内角点")
print(f"结果图像已保存至: {output_path}")
else:
print("检测失败:未找到完整的棋盘格内角点")
print("请检查:1) 棋盘格是否完整出现在图像中;2) pattern_size是否与实际棋盘格匹配")
关键说明
cv2.findChessboardCorners返回的corners是一个形状为(N,1,2)的数组,其中N为内角点总数(本例中为9×6=54),每个角点以(x, y)像素坐标存储。检测顺序为从左到右、从上到下逐行扫描。cv2.drawChessboardCorners会根据检测顺序自动用不同颜色绘制角点并用线条连接,便于观察角点排列是否正确。
验证方法
运行代码后,观察弹出的窗口:若检测成功,图像上会显示彩色圆点与连线,且连线呈现规则的网格状结构,控制台输出“检测成功”及角点数量54。若检测失败,请确认棋盘格图像完整无遮挡、边缘未被裁剪,并核对pattern_size是否与图像中棋盘格的实际内角数一致。保存的chessboard_corners_result.jpg应与窗口中显示的内容一致。
运行与验证
将上述代码保存为detect_corners.py,在命令行执行python detect_corners.py。程序会弹出显示检测结果的窗口,按任意键关闭窗口后,结果图像将保存至当前目录。判定标准为:控制台输出“检测成功!共检测到 54 个内角点”,且保存的图像中角点连线呈规则的网格状,无错位或缺失。