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;
}
}
评论看到就回。 没看到不回。