目录
概述对象测量多边形拟合计算对象中心
【OpenCV】⚠️高手勿入! 半小时学会基本操作 ⚠️ 对象测量
概述
OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大. 今天小白就带大家一起携手走进 OpenCV 的世界.
对象测量
对象测量可以帮助我们进行矩阵计算:
获取弧长与面积
多边形拟合
计算图片对象中心
原点距:
中心距:
图像重心坐标:
多边形拟合
步骤:
-
读取图片
转换成灰度图
二值化
轮廓检测
计算轮廓周长
多边形拟合
格式:
cv2.approxPolyDP(curve, epsilon, closed, approxCurve=None)
参数:
curve: 输入轮廓
epsilon: 逼近曲率, 越小表示相似逼近越厉害
closed: 是否闭合
代码:
import cv2 from matplotlib import pyplot as plt # 读取图片 image = cv2.imread(\"polygon.jpg\") image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 二值化 ret, thresh = cv2.threshold(image_gray, 127, 255, cv2.THRESH_OTSU) # 计算轮廓 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 轮廓近似 perimeter = cv2.arcLength(contours[0], True) approx = cv2.approxPolyDP(contours[0], perimeter * 0.1, True) # 绘制轮廓 result1 = cv2.drawContours(image.copy(), contours, 0, (0, 0, 255), 2) result2 = cv2.drawContours(image.copy(), [approx], -1, (0, 0, 255), 2) # 图片展示 f, ax = plt.subplots(1, 2, figsize=(12, 8)) # 子图 ax[0].imshow(cv2.cvtColor(result1, cv2.COLOR_BGR2RGB)) ax[1].imshow(cv2.cvtColor(result2, cv2.COLOR_BGR2RGB)) # 标题 ax[0].set_title(\"contour\") ax[1].set_title(\"approx\") plt.show()
输出结果:
计算对象中心
cv2.moments()
可以帮助我们得到轮距, 从而进一步计算图片对象的中心.
格式:
cv2.moments(array, binaryImage=None)
参数:
array: 轮廓
binaryImage: 是否把 array 内的非零值都处理为 1, 默认为 None
例 1:
import numpy as np import cv2 # 读取图片 image = cv2.imread(\"shape.jpg\") image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 二值化 ret, thresh = cv2.threshold(image_gray, 0, 255, cv2.THRESH_OTSU) # 获取轮廓 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 遍历每个轮廓 for i, contour in enumerate(contours): # 面积 area = cv2.contourArea(contour) # 外接矩形 x, y, w, h = cv2.boundingRect(contour) # 获取论距 mm = cv2.moments(contour) print(mm, type(mm)) # 调试输出 (字典类型) # 获取中心 cx = mm[\"m10\"] / mm[\"m00\"] cy = mm[\"m01\"] / mm[\"m00\"] # 获取 cv2.circle(image, (np.int(cx), np.int(cy)), 3, (0, 255, 255), -1) cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) # 图片展示 cv2.imshow(\"result\", image) cv2.waitKey(0) cv2.destroyAllWindows() # 保存图片 cv2.imwrite(\"result1.jpg\", image)
输出结果:
{\’m00\’: 8500.5, \’m10\’: 1027805.8333333333, \’m01\’: 2991483.6666666665, \’m20\’: 131713199.41666666, \’m11\’: 365693040.4583333, \’m02\’: 1061366842.5833333, \’m30\’: 17848380183.95, \’m21\’: 47383693552.933334, \’m12\’: 131067057115.4, \’m03\’: 379419590249.80005, \’mu20\’: 7439941.251379013, \’mu11\’: 3989097.993609071, \’mu02\’: 8608236.862088203, \’mu30\’: 123631672.32175827, \’mu21\’: 66721478.995661736, \’mu12\’: -71778847.06811166, \’mu03\’: -153890589.33666992, \’nu20\’: 0.10296285178405724, \’nu11\’: 0.05520593397050295, \’nu02\’: 0.11913113104071384, \’nu30\’: 0.01855746134472764, \’nu21\’: 0.010015081443714638, \’nu12\’: -0.010774206599494254, \’nu03\’: -0.023099409797678556} <class \’dict\’>
{\’m00\’: 15986.0, \’m10\’: 6026846.0, \’m01\’: 5179910.0, \’m20\’: 2292703160.333333, \’m11\’: 1952864629.0, \’m02\’: 1698884573.6666665, \’m30\’: 879850714149.0, \’m21\’: 742898718990.0, \’m12\’: 640491821107.3334, \’m03\’: 563738081200.0, \’mu20\’: 20535469.371490955, \’mu11\’: -1620.4595272541046, \’mu02\’: 20449217.223528624, \’mu30\’: -223791.80407714844, \’mu21\’: 151823.5922050476, \’mu12\’: 209097.09715557098, \’mu03\’: -152351.75524902344, \’nu20\’: 0.08035724088041474, \’nu11\’: -6.34101194440178e-06, \’nu02\’: 0.08001972803837157, \’nu30\’: -6.926194062792776e-06, \’nu21\’: 4.698830090131295e-06, \’nu12\’: 6.471403538830498e-06, \’nu03\’: -4.715176353366703e-06} <class \’dict\’>
{\’m00\’: 11396.0, \’m10\’: 6176598.0, \’m01\’: 2597707.833333333, \’m20\’: 3349665027.0, \’m11\’: 1407949570.5833333, \’m02\’: 655725464.8333333, \’m30\’: 1817641012813.0, \’m21\’: 763562731879.1167, \’m12\’: 355401284084.75, \’m03\’: 178062030454.85, \’mu20\’: 1967338.8985610008, \’mu11\’: -324.81426215171814, \’mu02\’: 63580327.29723644, \’mu30\’: -21712.3154296875, \’mu21\’: 9988180.769364119, \’mu12\’: 186586.19526672363, \’mu03\’: -396148296.0755005, \’nu20\’: 0.015148662774911266, \’nu11\’: -2.501095121647356e-06, \’nu02\’: 0.48957347310563326, \’nu30\’: -1.5661200090835562e-06, \’nu21\’: 0.0007204523998327835, \’nu12\’: 1.3458554191159022e-05, \’nu03\’: -0.028574371768747265} <class \’dict\’>
{\’m00\’: 11560.0, \’m10\’: 4184863.0, \’m01\’: 1485772.0, \’m20\’: 1524366924.3333333, \’m11\’: 537875136.1666666, \’m02\’: 203000229.0, \’m30\’: 558641678337.5, \’m21\’: 195927630288.0, \’m12\’: 73490515262.5, \’m03\’: 29185458885.0, \’mu20\’: 9394750.564388752, \’mu11\’: 7292.807151079178, \’mu02\’: 12038426.579238743, \’mu30\’: -36898.54187011719, \’mu21\’: 58255.2828142643, \’mu12\’: 46557.39966964722, \’mu03\’: -74896.38109207153, \’nu20\’: 0.07030230843432154, \’nu11\’: 5.457315488828541e-05, \’nu02\’: 0.0900853271874644, \’nu30\’: -2.568115896721007e-06, \’nu21\’: 4.0545319755426715e-06, \’nu12\’: 3.2403664790463073e-06, \’nu03\’: -5.21274221530133e-06} <class \’dict\’>
{\’m00\’: 7136.5, \’m10\’: 931499.3333333333, \’m01\’: 837811.3333333333, \’m20\’: 126603461.91666666, \’m11\’: 109342970.95833333, \’m02\’: 104031211.58333333, \’m30\’: 17834967892.7, \’m21\’: 14861464047.05, \’m12\’: 13575875235.816666, \’m03\’: 13540680151.900002, \’mu20\’: 5018510.189567342, \’mu11\’: -13253.86603589356, \’mu02\’: 5673777.230110094, \’mu30\’: -177930.16611862183, \’mu21\’: 1921792.6864708662, \’mu12\’: 201480.14046394825, \’mu03\’: -4564410.182851791, \’nu20\’: 0.09853811951621429, \’nu11\’: -0.00026023879322029775, \’nu02\’: 0.11140424502299628, \’nu30\’: -4.135579833554871e-05, \’nu21\’: 0.00044667676380089435, \’nu12\’: 4.682945134828951e-05, \’nu03\’: -0.0010608927713634498} <class \’dict\’>
例 2:
import numpy as np import cv2 # 读取图片 image = cv2.imread(\"shape.jpg\") image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 二值化 ret, thresh = cv2.threshold(image_gray, 0, 255, cv2.THRESH_OTSU) # 获取轮廓 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 遍历每个轮廓 for i, contour in enumerate(contours): # 面积 area = cv2.contourArea(contour) # 外接矩形 x, y, w, h = cv2.boundingRect(contour) # 获取论距 mm = cv2.moments(contour) # 获取中心 cx = mm[\"m10\"] / mm[\"m00\"] cy = mm[\"m01\"] / mm[\"m00\"] # 获取 cv2.circle(image, (np.int(cx), np.int(cy)), 3, (0, 255, 255), -1) cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) # 多变形拟合 approxCurve = cv2.approxPolyDP(contour, 4, True) print(approxCurve.shape) # 圆圈 if approxCurve.shape[0] > 10: cv2.drawContours(image, contours, i, (0, 255, 0), 2) # 绿色 # 4-10边形 if 10 >= approxCurve.shape[0] > 3: cv2.drawContours(image, contours, i, (240, 32, 160), 2) # 紫色 # 三角形 if approxCurve.shape[0] == 3: cv2.drawContours(image, contours, i, (250, 206, 135), 2) # 蓝色 # 图片展示 cv2.imshow(\"result\", image) cv2.waitKey(0) cv2.destroyAllWindows() # 保存图片 cv2.imwrite(\"result2.jpg\", image)
输出结果:
(3, 1, 2)
(6, 1, 2)
(7, 1, 2)
(16, 1, 2)
(10, 1, 2)
暂无评论内容