0


C++/OpenCV connectedComponentsWithStats函数异常解决方案(查找连通分量问题)

文章目录

首先我们简单了解下Mat类型type()函数与connectedComponentsWithStats函数

一、Mat.type()函数

命名规则为CV_(位数)+(数据类型)+(通道数)
U:代表

unsigned int

无符号整形
S:代表

signed int

有符号整形
F:代表

float

单精度浮点型
C(number of channels):代表一张图片的通道数
函数返回值与

Mat

类型对应如下:
C1C2C3C4CV_8U081624CV_8S191725CV_16U2101826CV_16S3111927CV_32S4122028CV_32F5132129CV_64F6142230


二、简单了解connectedComponentsWithStats函数

int connectedComponentsWithStats(InputArray image, OutputArray labels,
OutputArray stats, OutputArray centroids,int connectivity = 8, int
ltype = CV_32S);

前四个参数均为

Mat

类型,第一个参数为输入已有图片,第二三四参数为执行函数后有关图片的输出结果。以下为简易说明:

1.**注意!第一参数

image

需输入一个二值化图片,且格式为

CV_8UC1

**(可能只是单通道图片,有待考证)
2.输出

labels

CV_32SC1

类型的标签图,不同的连通域被赋该连通域的标签的值。
3.

stats

包含了标签为i的连通域的一些信息,可以如下访问标签为i的连通域的面积

stats.at<int>(i, CC_STAT_AREA)//标签为i的连通域的面积

4.连通域的个数有两种得到方式
(1)

该函数返回值

(2)

int labelNum = Imgcentriods.rows;

三、问题代码

    Mat image;
    image =imread("二值化图片.bmp");
    Mat labels, stats, centriods;int labelNum =connectedComponentsWithStats(image, labels, Imgstats, centriods,8);

第四行代码异常报错如下:

0x00007FFC77EB4F69 处(位于 testcv.exe 中)有未经处理的异常: Microsoft C++ 异常: cv::Exception,位于内存位置 0x00000063B13FD840 处。
异常截图

命令行窗口报错如下:

OpenCV(4.5.5) Error: Assertion failed (L.channels() == 1 &&
I.channels() == 1)
in cv::connectedComponents_sub1, file C:\build\master_winpack-build-win64-vc15\opencv\modules\imgproc\src\connectedcomponents.cpp, line 5623


四、原因分析

传递给该函数的图像

image.type()

是16,即image的Mat类型是

CV_8UC3

(三通道)。而该函数第一个参数应该是

CV_8UC1

Mat

类型(单通道)。


五、解决方案

修改

image

图片格式为

CV_8UC1

,因为

image

本身是二值化后三通道文件,所以BGR三者的值相等,要么为(ff,ff,ff)16,要么为(00,00,00)16.。修改为单通道图片只需(i,j)像素点的值取原图该点BGR其一的值即可。
代码如下:

    Mat image;
    image =imread("二值.bmp");
    Mat img8bit =Mat::zeros(Size(image.cols, image.rows), CV_8UC1);//初始化CV_8UC1的Mat图片,初始值为0(黑色)for(int i =0; i < image.rows; i++){
        uchar* data = image.ptr<uchar>(i);for(int j =0; j < img.cols *3; j = j +3){
            img8bit.at<uchar>(i, j /3)= data[j];}}

六、完整代码

#include<opencv2/opencv.hpp>#include<iostream>usingnamespace cv;usingnamespace std;intmain(){
    Mat image;
    image =imread("二值.bmp");//cout << "image二值化文件类型值:" << image.type() << endl;
    Mat img8bit =Mat::zeros(Size(image.cols, image.rows), CV_8UC1);for(int i =0; i < image.rows; i++){
        uchar* data = image.ptr<uchar>(i);for(int j =0; j < image.cols *3; j = j +3){
            img8bit.at<uchar>(i, j /3)= data[j];}}//cout << "img8bit文件类型值:" << img8bit.type() << endl;
    Mat labels, stats, centriods;int labelNum =connectedComponentsWithStats(img8bit, labels, stats, centriods,8);waitKey(0);return0;}

两则cout执行结果:

image二值化文件类型值:16
img8bit文件类型值:0

对应:
image格式:

CV_8UC3

img8bit格式:

CV_8UC1

七、部分引用

https://blog.csdn.net/weixin_51326570/article/details/113932128
https://blog.csdn.net/qq_40119386/article/details/89085075
https://stackoverflow.com/questions/41257336/opencv-error-assertion-failed-l-channels-1-i-channels-1-in-conne

八、笔者想说的话

以上为笔者在学习opencv过程中总结所感,希望对大家有所帮助!(第一次发csdn有、、小激动,要是点个赞就更好了


本文转载自: https://blog.csdn.net/meehotel/article/details/124773326
版权归原作者 meehotel 所有, 如有侵权,请联系我们删除。

“C++/OpenCV connectedComponentsWithStats函数异常解决方案(查找连通分量问题)”的评论:

还没有评论