OpenCV自带寻找轮廓的函数,流程是:获取灰度图→图片二值化→寻找轮廓
直接上代码(Python版)
import cv2
def find_contours(imgname):
img = cv2.imread(imgname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite("gray.jpg", gray)
_, binary = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)
cv2.imwrite("binary.jpg", binary)
image, contours, hierarchy = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
cv2.drawContours(img, contours, -1, (0, 0, 255), 3)
cv2.putText(
img,
"{:.3f}".format(len(contours)),
(30, 30),
cv2.FONT_HERSHEY_SIMPLEX,
1.0,
(0, 255, 0),
1,
)
# cv2.imshow("img", img)
cv2.imwrite("contours.jpg", img)
cv2.waitKey(0)
if __name__ == "__main__":
img = "test.jpg"
find_contours(img)
函数说明:
(1)cvtColor:将彩色图转为灰度图
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );
//参数解释:
//InputArray src: 输入图像即要进行颜色空间变换的原图像,可以是Mat类
//OutputArray dst: 输出图像即进行颜色空间变换后存储图像,也可以Mat类
//int code: 转换的代码或标识,即在此确定将什么制式的图片转换成什么制式的图片
//int dstCn = 0: 目标图像通道数,如果取值为0,则由src和code决定
(2)threshold:将图像二值化为黑白图片
double cv::threshold(
cv::InputArray src, // 输入图像
cv::OutputArray dst, // 输出图像
double thresh, // 阈值
double maxValue, // 向上最大值
int thresholdType // 阈值化操作的类型
);
(3)findContours:寻找图像中物体的轮廓
void cv::findContours ( InputOutputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
//image:输入图像,图像必须为8-bit单通道图像,图像中的非零像素将被视为1,0像素保留其像素值,故加载图像后会自动转换为二值图像。我们同样可以使用
//contours:检测到的轮廓,每个轮廓都是以点向量的形式进行存储即使用point类型的vector表示
//hierarchy:可选的输出向量(std::vector),包含了图像的拓扑信息,作为轮廓数量的表示hierarchy包含了很多元素,每个轮廓contours[i]对应hierarchy中hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓,前一个轮廓,父轮廓,内嵌轮廓的索引,如果没有对应项,则相应的hierarchy[i]设置为负数。
//mode轮廓检索模式,可以通过cv::RetrievalModes()查看详细信息
(4)drawContours():
void cv::drawContours ( InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point()
)
//image:输入输出图像,Mat类型即可
//contours:使用findContours检测到的轮廓数据,每个轮廓以点向量的形式存储,point类型的vector
//contourIdx:绘制轮廓的只是变量,如果为负值则绘制所有输入轮廓
//color:轮廓颜色
//thickness:绘制轮廓所用线条粗细度,如果值为负值,则在轮廓内部绘制
//lineTpye:线条类型,有默认值LINE_8
运行后得到原图、灰度图、二值化图、轮廓图分别如下
原图
灰度图
二值化
轮廓图