基于OpenCV给二值图像中不同邻域做标记

标记8连通邻域

void lableConnectedRegion(Mat &img, Mat &labelImg, vector<int> &resLabelSet)
{
    uchar fgPix = 255;
    uchar bgPix = 0;
    resLabelSet.clear();
    resLabelSet.push_back(0);
    labelImg.create(img.size(), CV_32SC1);
    labelImg = Scalar(0);

    vector<int> labelSet(1, 0);
    int label = 1;

    // 初步打标签
    for(int ver = 0; ver < img.rows; ++ver) {
        for(int hor = 0; hor < img.cols; ++hor) {
            if(img.at<uchar>(ver, hor) == fgPix) {
                int upLabel = labelImg.at<int>( MAX2(ver - 1, 0), hor);
                int leftLabel = labelImg.at<int>(ver, MAX2(hor - 1, 0));
                int upLeftLabel = labelImg.at<int>(MAX2(ver - 1, 0), MAX2(hor - 1, 0));

                vector<int> set;
                set.push_back(upLabel);
                set.push_back(leftLabel);
                set.push_back(upLeftLabel);
                sort(set.begin(), set.end());
                int zeroCnt = 0;
                for(size_t i = 0; i < set.size(); ++i) {
                    if(set[i] == 0) zeroCnt++;
                }

                if(zeroCnt == 3) {
                    labelImg.at<int>(ver, hor) = label;
                    labelSet.push_back(label);
                    ++label;
                }
                else {
                    labelImg.at<int>(ver, hor) = set[zeroCnt];
                    if(zeroCnt == 1) {
                        if(labelSet[set[2]] > set[1]) labelSet[set[2]] = set[1];
                    }
                    else if(zeroCnt == 0) {
                        if(labelSet[set[1]] > set[0]) labelSet[set[1]] = set[0];
                        if(labelSet[set[2]] > set[0]) labelSet[set[2]] = set[0];
                    }
                }
            }
        }
    }
    if(1 == label) return;

    // 建立标签之间的关系
    for(size_t i = 1; i < labelSet.size(); ++i) {
        if(i != labelSet[i]) {
            labelSet[i] = labelSet[labelSet[i]];
        }
    }

    // 打新标签
    for(int ver = 0; ver < img.rows; ++ver) {
        int *ptr = labelImg.ptr<int>(ver);
        for(int hor = 0; hor < img.cols; ++hor) {
            ptr[hor] = labelSet[ptr[hor]];
        }
    }

    // 合并标签
    for(size_t i = 1; i < labelSet.size(); ++i) {
        if(labelSet[i] > resLabelSet.back()) resLabelSet.push_back(labelSet[i]);
    }
}

上个色

void Color(Mat &img, Mat labelImg, int label, int b, int g, int r)
{
    for(int ver = 0; ver < img.rows; ++ver) {
        for(int hor = 0; hor < img.cols; ++hor) {
            if( label == labelImg.at<int>(ver, hor) ) {
                img.at<Vec3b>(ver, hor)[0] = b;
                img.at<Vec3b>(ver, hor)[1] = g;
                img.at<Vec3b>(ver, hor)[2] = r;
            }
        }
    }
}


int main(int argc, char *argv[])
{
    Mat img = imread(argv[1]);
    vector<Mat> chan;
    split(img, chan);
    Mat gray = chan[0];
    imshow("gray", gray);
    waitKey(0);

    Mat labelImg(gray.size(), CV_32SC1);
    vector<int> labelSet;
    lableConnectedRegion(gray, labelImg, labelSet);

    for(int i = 1; i < labelSet.size(); ++i) {
        Color(img , labelImg, i, rand() % 256, rand() % 256, rand() % 256);
    }
    imshow("color", img);
    waitKey(0);

    return 0;
}

给不同邻域上个色
这里写图片描述

这里写图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值