**bwlabel** 通过openCV和cpp实现的matlab函数

bwlabel 通过openCV和cpp实现的matlab函数

第一次写博文

初始的代码转载于此:www.cnblogs.com/waring/p/4233705.html

因为在用该网站的代码时,遇到很多问题,调试也一直调试不成功,于是本来准备开始自己完全实现,到后面发现还是异想天开了 ,我把这个代码用来光斑的图像处理,还是比较成功的,其他类型的图片就不清楚了
直接先上主代码:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<string>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace std;
using namespace cv;

Mat bwlabel(const Mat in, int * num)
{//对连通对象进行标注
	Mat result = Mat::zeros(in.size(), CV_8UC1);
    int num_runs = number_of_runs(in); 
	cout << num_runs << endl;
    int * hang = new int[num_runs];
    int * liehead = new int[num_runs];
    int * lietail = new int[num_runs];
    int * labels = new int[num_runs];
    memset(hang, '\0', sizeof(int)*num_runs);
	memset(liehead, '\0', sizeof(int)*num_runs);
	memset(lietail, '\0', sizeof(int)*num_runs);
	memset(labels, 0, sizeof(int)*num_runs);

	Getlocation(in, &num_runs, hang, liehead, lietail); 
/*	for (int i = 0; i < num_runs; i++) {
		cout << hang[i] << "-";
	}cout << endl;
	for (int i = 0; i < num_runs; i++) {
		cout << liehead[i] << "-";
	}cout << endl;
	for (int i = 0; i < num_runs; i++) {
		cout << lietail[i] << "-";
	}cout << endl;*/
    first_pass(liehead, lietail, hang, labels, num_runs); 
/*	for (int i = 0; i < num_runs; i++) {
		cout << labels[i] << "-";
	}cout << endl;
	*/
    int number = 1;
    for(int i = 0; i < num_runs; i++)
    {
        uchar * p_row = result.ptr<uchar>(hang[i]);
        for(int j = liehead[i]; j <= lietail[i]; j++)
            p_row[j] = labels[i];
        if(number < labels[i])
            number = labels[i];
    }
    if(num != NULL)
        *num = number;
	
    delete [] hang;
    delete [] liehead;
    delete [] lietail;
    delete [] labels;
    return result;
	//return in;
}

记住传进来的Mat in图像一定要是灰度图
第一个函数 number_of_runs 先计算有多少行团 ;
本来我自己写了一个计算行团,创建了一个大小一样的空白图,并初次标定的函数,结果调试失败了,所以用了他这个值计算了行团数的函数。
第二个函数 Getlocation 记录每个”行团“的行列头尾信息;
转载网站代码很奇怪 计算了多少行团,但是行列头尾信息的记录次数却不同,我就自己实现了这个函数。
第三个函数 first_pass 看转载网站解释
代码里的注释都是调试查看过程。

上三个小函数代码:

void first_pass(const int sc[], const int ec[], const int r[],int labels[], const int num_runs)
{
    int cur_row = 0;
    int next_label = 1;
    int first_run_on_prev_row = -1;
    int last_run_on_prev_row = -1;
    int first_run_on_this_row = 0;
    int offset = 1;
    int * equal_i = new int[num_runs];
    int * equal_j = new int[num_runs];
    int equal_idx = 0;

    for(int k = 0; k < num_runs; k++)
    {
        if(r[k] == cur_row + 1)
        {
            cur_row += 1;
            first_run_on_prev_row = first_run_on_this_row;
            first_run_on_this_row = k;
            last_run_on_prev_row = k - 1;
        }
        else if(r[k] > cur_row + 1)
        {
            first_run_on_prev_row = -1;
            last_run_on_prev_row = -1;
            first_run_on_this_row = k;
            cur_row = r[k];
        }
        if(first_run_on_prev_row >= 0)
        {
            int p = first_run_on_prev_row;
            while(p <= last_run_on_prev_row && sc[p] <= (ec[k] + offset))
            {
                if(sc[k] <= ec[p] + offset)
                {
                    if(labels[k] == 0)
                        labels[k] = labels[p];
                    else if(labels[k] != labels[p])
                    {
                        //labels[p] = labels[k];
                        equal_i[equal_idx] = labels[k];
                        equal_j[equal_idx] = labels[p];
                        equal_idx += 1;
                    }
                }
                p += 1;
            }
        }
        if(labels[k] == 0)
        {
            labels[k] = next_label++;
        }
    }
    /// process labels
    for(int i = 0; i < equal_idx; i++)
    {
        int max_label = equal_i[i] > equal_j[i] ? equal_i[i] : equal_j[i];
        int min_label = equal_i[i] < equal_j[i] ? equal_i[i] : equal_j[i];
        for(int j = 0; j < num_runs; j++)
        {
            if(labels[j] == max_label)
                labels[j] = min_label;
        }
    }
    delete [] equal_i;
    delete [] equal_j;
    /process ignore labels
    int * hist = new int[next_label];
    int * non_labels = new int[next_label];
    memset(hist, 0, sizeof(int)*next_label);
    int non_num = 0;
    for(int i = 0; i < num_runs; i++)
    {
        hist[labels[i]]++;
    }
    for(int i = 1; i < next_label; i++)
    {
        if(hist[i] == 0)
            non_labels[non_num++] = i;
    }
    for(int j = 0; j < num_runs; j++)
    {
        int k = labels[j];
        for(int i = non_num-1; i >= 0; i--)
        {
            if(k > non_labels[i])
            {
                labels[j] -= (i+1);
                break;
            }
        }
    }
    delete [] hist;
    delete [] non_labels;
}

int number_of_runs(const Mat in)
{
	const int rows = in.rows; //cout << in.rows << endl;
    const int cols = in.cols; //cout << in.cols << endl;
    int result = 0;
    for(int row = 0; row < rows; row++)
    {
        const uchar * p_row = in.ptr<uchar>(row);
        if(p_row[0] != 0)
            result++;
        for(int col = 1; col < cols; col++)
        {
            if(p_row[col] != 0 && p_row[col-1] == 0)
                result++;
        }
    }
    return result;
}
void Getlocation(const Mat in, int *n, int hang[], int liehead[], int lietail[]) {
	//记录每个”行团“的行列头尾信息,
	const int rows = in.rows;
	const int cols = in.cols;
	int k = 0;
	for (int row = 0; row < rows; row++)
	{
		const uchar * p_row = in.ptr<uchar>(row);
		for (int col = 0; col < cols; col++) {
			if (p_row[col] != 0) {
				if (col == 0 || (col > 0 && (p_row[col - 1] == 0))) {
					hang[k] = row;
					liehead[k] = col;
				}
				if ((col == cols - 1) || ((col < cols - 1) && (p_row[col + 1] == 0))) {
					lietail[k] = col;
					k++;
				}
			}

		}
	}
	if (k != *n)
	{
		cout << "There's a big problem,k=" << k << endl;
	}

}

评论看到就回。 没看到不回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值