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;
}
方法2
#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);
}