存储影像中的光滑线段__源码

# include <stdio.h>
# include<iostream>
# include <opencv2/opencv.hpp>
# include<time.h>
using namespace std;
using namespace cv;

typedef struct loc_and_degree
{
	CvPoint location;
	/*float distance;
	float degree;*/
	int flag = 0;
}l_and_d;


int main()
{
	Mat source = imread("123.png", 1);
	
	Mat draw( 608,608, CV_8UC3, Scalar(0, 0, 0));


	vector<CvPoint> all_white_pixes_in_image;//影像中所有白色点的位置
	CvPoint white_pixes_location;
	
	for (int i = 0; i < source.rows; i++)
	{
		Vec3b * ptr_color = source.ptr<Vec3b>(i);
		for (int j = 0; j < source.cols; j++)
		{
			int value = (*ptr_color)[0] + (*ptr_color)[1] + (*ptr_color)[2];
			if ((0 < value) && value <= 765)
			{
				white_pixes_location.x = j;
				white_pixes_location.y = i;
				all_white_pixes_in_image.push_back(white_pixes_location);
			}
			ptr_color++;
		}
	}
	vector<CvPoint> ::iterator start = all_white_pixes_in_image.begin(), end = all_white_pixes_in_image.end();
	for (start; start < end; start++)
	{
		circle(draw, *start, 0.5, Scalar(255,255,255), -1);//在图像中画出特征点,2是圆的半径
	}
	imshow("图像", draw);
	//waitKey();
	//通过八邻域找端点(extreme_point)
	int neighbourhood_x[] = { -1,-1,-1, 0,0, 1,1,1 };//竖向八邻域
	int neighbourhood_y[] = { -1, 0, 1,-1,1,-1,0,1 };
	vector<CvPoint> extreme_point;//存放端点库
	CvPoint extreme_point_location;//端点
	vector<CvPoint>::iterator start2 = all_white_pixes_in_image.begin(), end2 = all_white_pixes_in_image.end();
	for (start2; start2 < end2; start2++)
	{
		Vec3b color = 0;
		int value = 0;
		for (int k = 0; k < 8; k++)
		{
			color = draw.at<Vec3b>(start2->y + neighbourhood_y[k],start2->x + neighbourhood_x[k]);
			value += int(color[0] + color[1] + color[2]);
		}
		if ( value== 765 )//九宫格中只有2个白色像素点的位置为端点
		{
			extreme_point_location.x = start2->x;
			extreme_point_location.y = start2->y;
			extreme_point.push_back(extreme_point_location);
		}
	}
	
//从2个端点,选择单个端点,并将直线存储
	CvPoint site1;
	vector<CvPoint> sites1;
	l_and_d point_sign;
	vector<l_and_d> line,line1;
	for (auto &element : all_white_pixes_in_image)//初始化所有白点并将标志位初始化为0
	{
		point_sign.location = element;
		line.push_back(point_sign);
	}

	for (auto &element : extreme_point)
	{
		for (int i = 0; i < line.size(); i++)//将白点中的端点初始化为1
		{
			if (line[i].location.x == element.x && line[i].location.y == element.y)
			{
				line[i].flag = 1;
			}
		}
	}

	line1 = line;
	vector<vector<CvPoint>>final_line;//存放线段点
	for (auto &element : line)
	{
		if (element.flag == 1)
		{
			vector<CvPoint>temp;
			element.flag = 3;
			temp.push_back(element.location);
			CvPoint temp1;
			int l = 1;
			l_and_d add_location;
			while (l)
			{
				int count = 0;
				for (int k = 0; k < 8; k++)
				{
					temp1 = CvPoint(element.location.x + neighbourhood_x[k], element.location.y + neighbourhood_y[k]);
					Vec3b color = draw.at<Vec3b>(temp1.y, temp1.x);
					int value = color[0] + color[1] + color[2];
					if (value == 765)
					{
						for (auto &element1 : line)
						{
							if (temp1.x == element1.location.x && temp1.y == element1.location.y && (element1.flag == 0 || element1.flag == 1))
							{
								
								if (element1.flag == 1)//判定是否为另一个端点,是的话将最后一个点填入,并退出循环
								{
									element1.flag = 3;
									temp.push_back(temp1);
									//element.location = element1.location;
									l=0;
								}

								element1.flag = 3;//使用过的点设置为3;
								temp.push_back(temp1);
								element.location = element1.location;
								
							}
						}
					}
				}
				
			}
			final_line.push_back(temp);
		}
	}
#if 0
	for (auto &element : line1)
	{
		if (element.flag == 1)
		{
			vector<CvPoint>temp;
			element.flag = 3;
			temp.push_back(element.location);
			CvPoint temp1;
			int l = 1;
			l_and_d add_location;
			while (l)
			{
				for (int k = 0; k < 8; k++)
				{
					temp1 = CvPoint(element.location.x + neighbourhood_x[k], element.location.y + neighbourhood_y[k]);
					Vec3b color = draw.at<Vec3b>(temp1.y, temp1.x);
					int value = color[0] + color[1] + color[2];
					if (value == 765)
					{
						for (auto &element1 : line1)
						{
							if (temp1.x == element1.location.x && temp1.y == element1.location.y && (element1.flag == 0 || element1.flag == 1))
							{

								if (element1.flag == 1)//判定是否为另一个端点,是的话将最后一个点填入,并退出循环
								{
									element1.flag = 3;
									temp.push_back(temp1);
									element.location = element1.location;
									l = 0;
								}
								else
								{
									element1.flag = 3;//使用过的点设置为3;
									temp.push_back(temp1);
									element.location = element1.location;
								}
							}
						}
					}
				}

			}
			final_line.push_back(temp);
		}
	}

#endif
	Mat  h(608, 608, CV_8UC3, Scalar(255, 255, 255));

	//Mat  h(9120, 14592, CV_8UC3, Scalar(255, 255, 255));
	vector<vector<CvPoint>>::iterator start9 = final_line.begin(), end9 = final_line.end();
	for (int i = 0; i < final_line.size(); i++)
	{
		for (int j = 0; j < final_line[i].size(); j++)
		{
			if(final_line[i].size() <1)
				continue;
			else
			circle(h, final_line[i][j], 0.5, Scalar(0, 0, 0), -1);
		}
	}
	imshow("haha.png",h);
	waitKey();

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_33661910/article/details/84995064