#include <cv.h>
#include <highgui.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
void dispel(Mat &src, bool mode, float ratio, bool neighborhood);
int main()
{
double t = (double)getTickCount();
// char* OutPath = "C:\\Users\\Administrator\\Desktop\\psb0.jpg";
Mat image = imread("1.bmp",-1);
Mat Src;
cvtColor(image,Src,CV_BGR2GRAY);
Mat Dst = Mat::zeros(Src.size(), CV_8UC1);
//二值化处理
for (int i = 0; i < Src.rows; ++i)
{
uchar* iData = Src.ptr<uchar>(i);
for (int j = 0; j < Src.cols; ++j)
{
if (iData[j] == 0 || iData[j] == 255) continue;
else if (iData[j] < 150)
{
iData[j] = 0;
//cout<<'#';
}
else if (iData[j] > 150)
{
iData[j] = 255;
//cout<<'!';
}
}
}
imshow("原图",Src);
imwrite("1.jpg",Src);
dispel(Src, 1, 0.2, 1);
imshow("Src", Src);
imwrite("2.jpg", Src);
cout << "Image Binary processed." << endl;
t = ((double)getTickCount() - t) / getTickFrequency();
cout << "Time cost: " << t << " sec." << endl;
waitKey(0);
return 0;
}
/*
seed_filling() 利用种子填充法找到一个区域,运用迭代法
label 标记图像
neighborhood 0为四邻域 ,1 为8邻域
区域内的点的集合
要判断的点
*/
void seed_filling( Mat &label, vector<Point> &grow_point, Point grow_seed, bool neighborhood, int point_limit)
{
label.at<unsigned char>(grow_seed.y, grow_seed.x) = 3;
// if(grow_point.size()>point_limit) return;
if (neighborhood == 0) //四邻域
{
if (grow_seed.x - 1 >= 0)
{
if (label.at<unsigned char>(grow_seed.y, grow_seed.x - 1) == 0) //左
{
Point grow_seed_temp(grow_seed.x - 1, grow_seed.y);
grow_point.push_back(grow_seed_temp);
seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);
}
}
if (grow_seed.x + 1 < label.cols)
{
if (label.at<unsigned char>(grow_seed.y, grow_seed.x + 1) == 0) //右
{
Point grow_seed_temp(grow_seed.x + 1, grow_seed.y);
grow_point.push_back(grow_seed_temp);
seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);
}
}
if (grow_seed.y - 1 >= 0)
{
if (label.at<unsigned char>(grow_seed.y - 1, grow_seed.x) == 0) //上
{
Point grow_seed_temp(grow_seed.x, grow_seed.y - 1);
grow_point.push_back(grow_seed_temp);
seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);
}
}
if (grow_seed.y + 1 < label.rows)
{
if (label.at<unsigned char>(grow_seed.y + 1, grow_seed.x) == 0) //下
{
Point grow_seed_temp(grow_seed.x, grow_seed.y + 1);
grow_point.push_back(grow_seed_temp);
seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);
}
}
}
else //八邻域
{
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
if (grow_seed.y + i >= 0 && grow_seed.y + i < label.rows
&&grow_seed.x + j>=0 && grow_seed.x +j< label.cols
&&label.at<unsigned char>(grow_seed.y + i, grow_seed.x + j) == 0
)
{
Point grow_seed_temp(grow_seed.x+j, grow_seed.y + i);
grow_point.push_back(grow_seed_temp);
seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);
}
}
}
}
}
/*//dispel()利用种子填充法用来祛除一副图像中的噪声小区域
src 与dst 均为单通道的图像
mode 用于表示祛除的小区域的颜色,0为白色,1为黑色
ratio表示祛除区域占整个图像的比例
neighborhood 0为四邻域 ,1 为8邻域
*/
void dispel(Mat &src, bool mode, float ratio, bool neighborhood)
{
Mat label_image(src.size(), CV_8UC1, Scalar::all(0)); //标签图像,用来标注每一个像素点被处理的情况 3表示已经经过处理或者不需要处理
for (int i = 0; i < src.rows; i++)
{
unsigned char *data = label_image.ptr<unsigned char>(i);
unsigned char *data0 = src.ptr<unsigned char>(i);
for (int j = 0; j < src.cols; j++)
{
if (mode == 0)
{
if (data0[j] == 0) data[j] = 3;
}
else
{
if (data0[j] == 255) data[j] = 3;
}
}
}
for (int i = 0; i < src.rows; i++)
{
for (int j = 0; j < src.cols; j++)
{
unsigned char *data = label_image.ptr<unsigned char>(i);
if (data[j] == 0)
{
vector<Point> grow_point; //一个区域的集合
Point grow_seed(j, i);
grow_point.push_back(grow_seed);
seed_filling(label_image, grow_point, grow_seed, neighborhood, src.size().area()* ratio);
cout << "点数" << grow_point.size() << endl;
if (grow_point.size() < src.size().area()* ratio)
{
for (int a = 0; a < grow_point.size(); a++)
{
src.at<unsigned char>(grow_point[a].y, grow_point[a].x)=255* mode;
}
}
}
}
}
}
利用区域生长算法祛除二值图像中的噪声区域
最新推荐文章于 2023-01-05 19:41:42 发布