赞
踩
cv::findContours
cv::findContours
是OpenCV中用于查找图像中对象轮廓的函数。轮廓是对象的边界,通常用于对象检测、分割和形状分析。cv::findContours
函数的基本用法如下:
cv::findContours(image, contours, hierarchy, mode, method, offset = cv::Point(0, 0));
image
: 输入的二值化图像(通常是灰度图像,经过阈值处理得到的二值图像)。contours
: 用于存储找到的轮廓的容器,通常是一个std::vector<std::vector<cv::Point>>
。hierarchy
: 可选参数,用于存储轮廓的层次结构信息。mode
: 轮廓检索模式,通常使用 cv::RETR_EXTERNAL
表示只检索最外层的轮廓。method
: 轮廓近似方法,通常使用 cv::CHAIN_APPROX_SIMPLE
表示只保留轮廓的端点。offset
: 可选参数,通常设置为 cv::Point(0, 0)
。cv::findContours
将在输入图像中查找轮廓,并将找到的轮廓保存在 contours
容器中。hierarchy
参数用于存储轮廓的层次结构信息,通常在分析多个轮廓之间的关系时使用。
以下是一个示例,演示如何使用 cv::findContours
函数来查找图像中的轮廓:
#include <opencv2/opencv.hpp> int main() { cv::Mat image = cv::imread("your_binary_image.jpg", cv::IMREAD_COLOR); cv::Mat grayImage, binaryImage; if (image.empty()) { std::cerr << "无法加载图像" << std::endl; return -1; } // 将图像转换为灰度图像 cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY); // 阈值处理,将图像转换为二值图像 cv::threshold(grayImage, binaryImage, 128, 255, cv::THRESH_BINARY); // 查找轮廓 std::vector<std::vector<cv::Point>> contours; cv::findContours(binaryImage, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 绘制轮廓 cv::Mat contourImage = cv::Mat::zeros(image.size(), CV_8UC3); cv::drawContours(contourImage, contours, -1, cv::Scalar(0, 0, 255), 2); cv::imshow("原始图像", image); cv::imshow("轮廓图像", contourImage); cv::waitKey(0); return 0; }
在这个示例中,我们首先将彩色图像转换为灰度图像,然后进行阈值处理得到二值图像。接下来,使用 cv::findContours
查找图像中的轮廓,并将其绘制到另一个图像上。这个示例只是演示了 cv::findContours
的基本用法,您可以根据具体的应用需要进一步处理找到的轮廓。
要对图像进行去噪、平滑、边缘检测和轮廓检测,然后允许通过滑动条调整参数以动态检测图形
#include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> // 回调函数,用于处理滑动条的变化 void trackbarCallback(int threshold, void* userdata) { cv::Mat* image = static_cast<cv::Mat*>(userdata); // 去噪处理(高斯滤波) cv::Mat denoisedImage; cv::GaussianBlur(*image, denoisedImage, cv::Size(5, 5), 0); // 边缘检测(Canny) cv::Mat edges; cv::cvtColor(denoisedImage, edges, cv::COLOR_BGR2GRAY); cv::Canny(edges, edges, threshold, threshold * 2); // 查找轮廓 std::vector<std::vector<cv::Point>> contours; cv::findContours(edges, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 绘制轮廓 cv::Mat contourImage = cv::Mat::zeros(image->size(), CV_8UC3); cv::drawContours(contourImage, contours, -1, cv::Scalar(0, 0, 255), 2); cv::imshow("动态边缘检测与轮廓", contourImage); } int main() { cv::Mat image = cv::imread("111.jpg", cv::IMREAD_COLOR); if (image.empty()) { std::cerr << "无法加载图像" << std::endl; return -1; } // 创建窗口 cv::namedWindow("动态边缘检测与轮廓", cv::WINDOW_NORMAL); int initialThreshold = 100; int maxThreshold = 500; // 创建滑动条 cv::createTrackbar("阈值", "动态边缘检测与轮廓", &initialThreshold, maxThreshold, trackbarCallback, &image); // 初始化 trackbarCallback(initialThreshold, &image); cv::waitKey(0); return 0; }
#include <opencv2/opencv.hpp> #include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace std; using namespace cv; #include <iostream> #include <fstream> using namespace cv; //包含cv命名空间 #include <opencv2/core/core.hpp> #define WINDOW_NAME1 "【原始图窗口】" //为窗口标题定义的宏 #define WINDOW_NAME2 "【轮廓图】" //为窗口标题定义的宏 //【全局变量声明部分】-------------------- - // 描述: 全局变量的声明 // Mat g_srcImage; Mat g_grayImage; int g_nThresh = 80; int g_nThresh_max = 255; RNG g_rng(12345); Mat g_cannyMat_output; vector<vector<Point>> g_vContours; vector<Vec4i> g_vHierarchy; //-------- -------------------【全局函数声明部分】----------------------- // 描述:全局函数的声明 static void ShowHelpText(); void on_ThreshChange(int, void*); // --【main()函数】--------------------------- // 描述: 控制台应用程序的入口函数, 我们的程序从这里开始执行 //- ------- int main(int argc, char** argv) { //【0】改变 console字体颜色 system("color 1F"); //【0】显示欢迎和帮助文字 ShowHelpText(); // 加载源图像 g_srcImage = imread("113.jpg", 1); if (!g_srcImage.data) { printf("读取图片错误, 请确定目录下是否有imread函数指定的图片存在~! \n"); return false; } // 转成灰度并模糊化降噪 cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY); blur(g_grayImage, g_grayImage, Size(3, 3)); // 创建窗口 namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE); imshow(WINDOW_NAME1, g_srcImage); //创建滚动条并初始化 createTrackbar("canny阈值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange); on_ThreshChange(0, 0); waitKey(0); return(0); } // -【on_ThreshChange()函数】-------------------- // 描述: 回调函数 //- void on_ThreshChange(int, void*) { // 用Canny算子检测边缘 Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3); // 寻找轮廓 findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); // 绘出轮廓 Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3); for (int i = 0; i < g_vContours.size(); i++) { Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值 drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point()); } // 显示效果图 imshow(WINDOW_NAME2, drawing); } //---------------------------【ShowHelpText()函数】------------------- // 描述: 输出一些帮助信息 //- static void ShowHelpText() { //输出欢迎信息和OpenCV版本 printf("\n\n\t\t\t 当前使用的OpenCV 版本为: " CV_VERSION); }
使用python方法来实现
import cv2 import numpy as np # 全局变量声明 g_srcImage = None g_grayImage = None g_nThresh = 80 g_nThresh_max = 255 g_rng = np.random.default_rng(12345) g_cannyMat_output = None g_vContours = None g_vHierarchy = None # 窗口标题定义 WINDOW_NAME1 = "原始图窗口" WINDOW_NAME2 = "轮廓图" # 回调函数 def on_ThreshChange(val): global g_nThresh g_nThresh = val # Canny边缘检测 canny_output = cv2.Canny(g_grayImage, g_nThresh, g_nThresh * 2, 3) # 寻找轮廓 contours, hierarchy = cv2.findContours(canny_output, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) color = (255, 0, 0) # Blue # 绘制轮廓 drawing = np.zeros_like(canny_output, dtype=np.uint8) for i, contour in enumerate(contours): color = (255, 0, 0) # Blu cv2.drawContours(drawing, contours, i, color, 2, cv2.LINE_8, hierarchy, 0) # 显示效果图 cv2.imshow(WINDOW_NAME2, drawing) # 主函数 if __name__ == "__main__": # 加载源图像 g_srcImage = cv2.imread("113.jpg") if g_srcImage is None: print("读取图片错误,请检查图片路径!") exit(1) # 转成灰度并模糊化降噪 g_grayImage = cv2.cvtColor(g_srcImage, cv2.COLOR_BGR2GRAY) g_grayImage = cv2.blur(g_grayImage, (3, 3)) # 创建窗口 cv2.namedWindow(WINDOW_NAME1, cv2.WINDOW_AUTOSIZE) cv2.imshow(WINDOW_NAME1, g_srcImage) # 创建滚动条并初始化 cv2.createTrackbar("canny阈值", WINDOW_NAME1, g_nThresh, g_nThresh_max, on_ThreshChange) # 等待用户操作 cv2.waitKey(0) cv2.destroyAllWindows()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。