基础轮廓查找
视频讲解如下:
当前系列所有demo下载地址:
https://github.com/GaoRenBao/OpenCv4-Demo
不同编程语言对应的OpenCv版本以及开发环境信息如下:
语言 | OpenCv版本 | IDE |
C# | OpenCvSharp4.4.8.0.20230708 | Visual Studio 2022 |
C++ | OpenCv-4.5.5-vc14_vc15 | Visual Studio 2022 |
Python | OpenCv-Python (4.6.0.66) | PyCharm Community Edition 2022.1.3 |
本章节给大家讲讲如何实现基础轮廓查找。当前代码主体还是使用毛星云的demo,C#和Python都是在C++版本的基础上转换过来的,三个版本的效果基本一致。
首先我们需要准备一张测试图片:

三组代码运行效果都是一样的,我这里就不一一展示了,最终运行效果如下:

C#版本代码如下:
C#版本需要安装“OpenCvSharp4”、“OpenCvSharp4.runtime.win”两个库才行。不然会报错。
如果需要使用“ BitmapConverter.ToBitmap”操作,则需要追加安装“OpenCvSharp4.Extensions”库。
using OpenCvSharp;
using System;
namespace demo
{
internal class Program
{
static void Main(string[] args)
{
// 【1】载入原始图,且必须以二值图模式载入
Mat srcImage = Cv2.ImRead("../../../images/flowers2.jpg", 0);
Cv2.ImShow("原始图", srcImage);
//【2】初始化结果图
Mat dstImage = new Mat(srcImage.Size(), MatType.CV_8UC3);
//【3】srcImage取大于阈值119的那部分
// Cv2.CvtColor(srcImage, srcImage, ColorConversionCodes.BGR2GRAY);
Cv2.Threshold(srcImage, srcImage, 119, 255, ThresholdTypes.Binary);
Cv2.ImShow("取阈值后的原始图", srcImage);
Point[][] contours = new Point[][] { };
HierarchyIndex[] hierarcy;
Cv2.FindContours(srcImage, out contours, out hierarcy, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null);
Random g_rng = new Random();
// 【6】遍历所有顶层的轮廓, 以随机颜色绘制出每个连接组件颜色
for (int index = 0; index < contours.Length; index++)
{
//随机生成bgr值
int b = g_rng.Next(255);//随机返回一个0~255之间的值
int g = g_rng.Next(255);//随机返回一个0~255之间的值
int r = g_rng.Next(255);//随机返回一个0~255之间的值
Cv2.DrawContours(dstImage, contours, index, new Scalar(b, g, r), -1, LineTypes.Link8, hierarcy);
}
//【7】显示最后的轮廓图
Cv2.ImShow("【C# 轮廓图】", dstImage);
Cv2.WaitKey(0);
}
}
}
C++版本代码如下:
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int main()
{
// 【1】载入原始图,且必须以二值图模式载入
Mat srcImage = imread("../images/flowers2.jpg", 0);
imshow("原始图", srcImage);
//【2】初始化结果图
Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
//【3】srcImage取大于阈值119的那部分
srcImage = srcImage > 119;
imshow("取阈值后的原始图", srcImage);
//【4】定义轮廓和层次结构
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
//【5】查找轮廓
findContours(srcImage, contours, hierarchy,RETR_CCOMP, CHAIN_APPROX_SIMPLE);
// 【6】遍历所有顶层的轮廓, 以随机颜色绘制出每个连接组件颜色
int index = 0;
for (; index >= 0; index = hierarchy[index][0])
{
Scalar color(rand() & 255, rand() & 255, rand() & 255);
drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy);
}
//【7】显示最后的轮廓图
imshow("轮廓图", dstImage);
waitKey(0);
}
Python版本代码如下:
import cv2
import numpy as np
import random
def zh_ch(string):
return string.encode("gbk").decode(errors="ignore")
# 【1】载入原始图
srcImage = cv2.imread("../images/flowers2.jpg", 0)
cv2.imshow("原始图", srcImage)
# 【2】初始化结果图
imgH = srcImage.shape[0]
imgW = srcImage.shape[1]
dstImage = cv2.UMat((imgW, imgH), cv2.CV_8UC3)
# 【3】srcImage取大于阈值119的那部分
ret,srcImage = cv2.threshold(srcImage,119,255,cv2.THRESH_BINARY)
cv2.imshow(zh_ch('取阈值后的原始图'), srcImage)
# 【4】查找轮廓
contours, hierarchy = cv2.findContours(srcImage,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
for i in range(0,len(contours)):
cv2.drawContours(dstImage, contours, i, (random.randint(0,255), random.randint(0,255), random.randint(0,255)), -1, 8, hierarchy)
cv2.imshow("dstImage", dstImage)
cv2.waitKey(0)
cv2.destroyAllWindows()