当前位置: 首页 > news >正文

企业网站建设策划网站作业代做

企业网站建设策划,网站作业代做,泰安软件开发公司哪家好,vps做vpn svn和网站由于项目的需要提取图像之中的一个接近于竖直的物体#xff0c;一般的方法是进行图像分割#xff0c;分割方式使用什么OTSU方式以及hsv方法等等。但是项目中使用的相机是黑白相机#xff0c;会受到一定的限制。因此想到的是使用线条提取方式。线条提取方式之中最好的方法是使…由于项目的需要提取图像之中的一个接近于竖直的物体一般的方法是进行图像分割分割方式使用什么OTSU方式以及hsv方法等等。但是项目中使用的相机是黑白相机会受到一定的限制。因此想到的是使用线条提取方式。线条提取方式之中最好的方法是使用canny算法但是这里不能够将接近竖直特征进行提取因此此处使用了Prewitt算子进行提取但是只用这个算法轮廓提取不出来就结合了一下canny算子。下面是我的思路感觉实现过程比较麻烦但是居然实现了[苦笑] 本次测试的案例是使用校门口的一个图片,图中存在很多的干扰,如下图所示 #include opencv2/opencv.hpp #include opencv2/highgui/highgui.hpp #include iostream #include opencv2/core.hpp #include opencv2/highgui.hpp #include opencv2/imgproc.hpp using namespace cv; using namespace std;void getPrewitt_oper(cv::Mat getPrewitt_horizontal, cv::Mat getPrewitt_vertical, cv::Mat getPrewitt_Diagonal1, cv::Mat getPrewitt_Diagonal2) {//水平方向getPrewitt_horizontal (cv::Mat_float(3, 3) -1, -1, -1, 0, 0, 0, 1, 1, 1);//垂直方向getPrewitt_vertical (cv::Mat_float(3, 3) -1, 0, 1, -1, 0, 1, -1, 0, 1);//对角135°getPrewitt_Diagonal1 (cv::Mat_float(3, 3) 0, 1, 1, -1, 0, 1, -1, -1, 0);//对角45°getPrewitt_Diagonal2 (cv::Mat_float(3, 3) -1, -1, 0, -1, 0, 1, 0, 1, 1);//逆时针反转180°得到卷积核cv::flip(getPrewitt_horizontal, getPrewitt_horizontal, -1);cv::flip(getPrewitt_vertical, getPrewitt_vertical, -1);cv::flip(getPrewitt_Diagonal1, getPrewitt_Diagonal1, -1);cv::flip(getPrewitt_Diagonal2, getPrewitt_Diagonal2, -1); }void edge_Prewitt(cv::Mat src, cv::Mat dst1, cv::Mat dst2, cv::Mat dst3, cv::Mat dst4, cv::Mat dst, int ddepth, double delta 0, int borderType cv::BORDER_DEFAULT) {//获取Prewitt算子cv::Mat getPrewitt_horizontal;cv::Mat getPrewitt_vertical;cv::Mat getPrewitt_Diagonal1;cv::Mat getPrewitt_Diagonal2;getPrewitt_oper(getPrewitt_horizontal, getPrewitt_vertical, getPrewitt_Diagonal1, getPrewitt_Diagonal2);//卷积得到水平方向边缘cv::filter2D(src, dst1, ddepth, getPrewitt_horizontal, cv::Point(-1, -1), delta, borderType);//卷积得到4垂直方向边缘cv::filter2D(src, dst2, ddepth, getPrewitt_vertical, cv::Point(-1, -1), delta, borderType);//卷积得到45°方向边缘cv::filter2D(src, dst3, ddepth, getPrewitt_Diagonal1, cv::Point(-1, -1), delta, borderType);//卷积得到135°方向边缘cv::filter2D(src, dst4, ddepth, getPrewitt_Diagonal2, cv::Point(-1, -1), delta, borderType);//边缘强度近似cv::convertScaleAbs(dst1, dst1); //求绝对值并转为无符号8位图cv::convertScaleAbs(dst2, dst2);cv::convertScaleAbs(dst3, dst3); //求绝对值并转为无符号8位图cv::convertScaleAbs(dst4, dst4);dst dst1 dst2;}//数组从大到小排序 void reserve(int x[], int n) {int i, j, temp;for (i 0; i n - 1; i) { //一共n个元素则需要比较n-1次for (j 0; j n - 1 - i; j) { //每一个元素需要比较的次数if (x[i] x[i j 1]) {temp x[i];x[i] x[i j 1];x[i j 1] temp;}}} }int main() {cv::Mat src cv::imread(楼.jpg);if (src.empty()) {return -1;}cout ?? endl;if (src.channels() 1) cv::cvtColor(src, src, CV_RGB2GRAY);cv::Mat dst, dst1, dst2, dst3, dst4, dst5;Mat src1 cv::imread(楼.jpg);Mat src2 cv::imread(楼.jpg);//medianBlur(src, src, 5); //均值滤波GaussianBlur(src, src, Size(5, 5), 0); //高斯滤波cout ?? endl;//注意要采用CV_32F因为有些地方卷积后为负数若用8位无符号则会导致这些地方为0edge_Prewitt(src, dst1, dst2, dst3, dst4, dst, CV_32F);cv::namedWindow(垂直边缘, CV_WINDOW_NORMAL);imshow(垂直边缘, dst2);cout ?? endl;//获取结构cv::Mat element1 cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));Mat out1;//进行形态学开运算操作 morphologyEx(dst2, out1, MORPH_OPEN, element1);//形态学开运算cv::namedWindow(xingtai, CV_WINDOW_NORMAL);imshow(xingtai, out1);//第二次进行形态学操作edge_Prewitt(dst2, dst1, out1, dst3, dst4, dst, CV_32F);cv::namedWindow(垂直边缘1, CV_WINDOW_NORMAL);imshow(垂直边缘1, out1);cout ?? endl;morphologyEx(out1, out1, MORPH_OPEN, element1);//形态学开运算cv::namedWindow(xingtai1, CV_WINDOW_NORMAL);imshow(xingtai1, out1);//获取结构cv::Mat element2 cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(10, 10));Mat out2;//进行形态学闭运算操作 morphologyEx(out1, out2, MORPH_CLOSE, element2);//形态学开运算cv::namedWindow(xingtai2, CV_WINDOW_NORMAL);imshow(xingtai2, out2);imwrite(xingtai2.jpg, out2);/*//膨胀运算将细小缝隙填补上,非必要Mat kernel getStructuringElement(0, Size(3, 3));dilate(out2, dst2, kernel);cv::namedWindow(膨胀, CV_WINDOW_NORMAL);imshow(膨胀, dst2);*/cv::threshold(out2, dst2, 5, 255, cv::THRESH_BINARY);cv::namedWindow(二值化, CV_WINDOW_NORMAL);imshow(二值化, dst2);cv::threshold(dst2, dst2, 5, 255, cv::THRESH_BINARY_INV);cv::namedWindow(反二值化, CV_WINDOW_NORMAL);imshow(反二值化, dst2);//进行形态学闭运算操作 morphologyEx(dst2, out2, MORPH_CLOSE, element2);//形态学开运算cv::namedWindow(xingtai3, CV_WINDOW_NORMAL);imshow(xingtai3, out2);imwrite(xingtai3.jpg, out2);/*cv::threshold(dst2, dst2, 5, 255, cv::THRESH_BINARY);cv::namedWindow(反二值化, CV_WINDOW_NORMAL);imshow(反二值化, dst2);imwrite(反二值化.jpg, dst2);*//*//膨胀运算将细小缝隙填补上,非必要Mat kernel getStructuringElement(0, Size(5, 5));dilate(out2, out2, kernel);cv::namedWindow(膨胀1, CV_WINDOW_NORMAL);imshow(膨胀1, out2);*/Canny(out2, dst2, 5, 10);cv::namedWindow(Canny, CV_WINDOW_NORMAL);imshow(Canny, dst2);imwrite(Canny.jpg, dst2);vectorVec4i lines;HoughLinesP(dst2, lines, 1, CV_PI / 180, 50, 200, 30);int Length[100] {0};//存放直线长度for (size_t i 0; i lines.size(); i){Vec4i I lines[i];double x1 I[0];double y1 I[1];double x2 I[2];double y2 I[3];//筛选满足条件的点if (abs(x1 - x2) abs(y1 - y2) 50){Length[i] sqrt( (x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2));//将满足条件的点画出line(src1, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);cout ( x1 , y1 ) ( x2 , y2 ) endl;//line(canny, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);}}Mat imgShow;imgShow src1;resize(imgShow, imgShow, Size(imgShow.cols / 4, imgShow.rows / 4));imshow(imgShow, imgShow);imwrite(shuchu.png, src1);reserve(Length, 100);for (int i 0; i 100; i) {cout 长度Length[i] endl; //输出排序后的数组元素}for (size_t i 0; i lines.size(); i){Vec4i I lines[i];double x1 I[0];double y1 I[1];double x2 I[2];double y2 I[3];cout sdjk endl;cout int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) endl;//筛选满足条件的点if ((int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) Length[0] ) || (int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) Length[1])){//将满足条件的点画出line(src2, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);cout djfkljsa ( x1 , y1 ) ( x2 , y2 ) endl;//line(canny, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);}}imgShow src2;resize(imgShow, imgShow, Size(imgShow.cols / 4, imgShow.rows / 4));imshow(imgShow2, imgShow);imwrite(shuchu2.png, src2);waitKey(0);return 0; } 调试过程:本次在进行调试过程之中进行了两次垂直检测迭代,进一步去排除水平线的干扰.使用形态学操作去除图片之中的空洞等等. 第一次进行垂直检测,注意这个地方只能够用特定的算子进行垂直检测,别的算子没有这个效果.  为了减少图片之中白色空洞的干扰,使用开操作. 重复上述操作,进一步排除水平线的干扰. 接下来是进行闭操作,将图中的白色线条尽可能连在一起,上图之中的楼左侧的线有一些断开了. 闭操作的缺陷是会产生小白点点.如下二值化过程 再进行一次反二值化,因为我不会用别的算子结合霍夫直线检测检测出来直线,只能转回去进行操作.  形态学操作,去除白点 canny一下检测出来轮廓 显示全部直线 直线提取我的方式是提取最长的两段直线。 在上述操作完成之后得到了物体的粗定位直线。 但是上面的算法还是存在相应的问题换了一个别的图像可能就检测的不准。发现问题就是出在了二值化的过程。 为了修正上方的算法的失败使用提取外部轮廓的方式进行求取将代码改了改。   #include opencv2/opencv.hpp #include opencv2/highgui/highgui.hpp #include iostream #include opencv2/core.hpp #include opencv2/highgui.hpp #include opencv2/imgproc.hpp using namespace cv; using namespace std;void getPrewitt_oper(cv::Mat getPrewitt_horizontal, cv::Mat getPrewitt_vertical, cv::Mat getPrewitt_Diagonal1, cv::Mat getPrewitt_Diagonal2) {//水平方向getPrewitt_horizontal (cv::Mat_float(3, 3) -1, -1, -1, 0, 0, 0, 1, 1, 1);//垂直方向getPrewitt_vertical (cv::Mat_float(3, 3) -1, 0, 1, -1, 0, 1, -1, 0, 1);//对角135°getPrewitt_Diagonal1 (cv::Mat_float(3, 3) 0, 1, 1, -1, 0, 1, -1, -1, 0);//对角45°getPrewitt_Diagonal2 (cv::Mat_float(3, 3) -1, -1, 0, -1, 0, 1, 0, 1, 1);//逆时针反转180°得到卷积核cv::flip(getPrewitt_horizontal, getPrewitt_horizontal, -1);cv::flip(getPrewitt_vertical, getPrewitt_vertical, -1);cv::flip(getPrewitt_Diagonal1, getPrewitt_Diagonal1, -1);cv::flip(getPrewitt_Diagonal2, getPrewitt_Diagonal2, -1); }void edge_Prewitt(cv::Mat src, cv::Mat dst1, cv::Mat dst2, cv::Mat dst3, cv::Mat dst4, cv::Mat dst, int ddepth, double delta 0, int borderType cv::BORDER_DEFAULT) {//获取Prewitt算子cv::Mat getPrewitt_horizontal;cv::Mat getPrewitt_vertical;cv::Mat getPrewitt_Diagonal1;cv::Mat getPrewitt_Diagonal2;getPrewitt_oper(getPrewitt_horizontal, getPrewitt_vertical, getPrewitt_Diagonal1, getPrewitt_Diagonal2);//卷积得到水平方向边缘cv::filter2D(src, dst1, ddepth, getPrewitt_horizontal, cv::Point(-1, -1), delta, borderType);//卷积得到4垂直方向边缘cv::filter2D(src, dst2, ddepth, getPrewitt_vertical, cv::Point(-1, -1), delta, borderType);//卷积得到45°方向边缘cv::filter2D(src, dst3, ddepth, getPrewitt_Diagonal1, cv::Point(-1, -1), delta, borderType);//卷积得到135°方向边缘cv::filter2D(src, dst4, ddepth, getPrewitt_Diagonal2, cv::Point(-1, -1), delta, borderType);//边缘强度近似cv::convertScaleAbs(dst1, dst1); //求绝对值并转为无符号8位图cv::convertScaleAbs(dst2, dst2);cv::convertScaleAbs(dst3, dst3); //求绝对值并转为无符号8位图cv::convertScaleAbs(dst4, dst4);dst dst1 dst2;}//数组从大到小排序 void reserve(int x[], int n) {int i, j, temp;for (i 0; i n - 1; i) { //一共n个元素则需要比较n-1次for (j 0; j n - 1 - i; j) { //每一个元素需要比较的次数if (x[i] x[i j 1]) {temp x[i];x[i] x[i j 1];x[i j 1] temp;}}} }int main() {cv::Mat src cv::imread(楼.jpg);if (src.empty()) {return -1;}cout ?? endl;if (src.channels() 1) cv::cvtColor(src, src, CV_RGB2GRAY);cv::Mat dst, dst1, dst2, dst3, dst4, dst5;Mat src1 cv::imread(楼.jpg);Mat src2 cv::imread(楼.jpg);//medianBlur(src, src, 5); //均值滤波GaussianBlur(src, src, Size(5, 5), 0); //高斯滤波cout ?? endl;//注意要采用CV_32F因为有些地方卷积后为负数若用8位无符号则会导致这些地方为0edge_Prewitt(src, dst1, dst2, dst3, dst4, dst, CV_32F);cv::namedWindow(垂直边缘, CV_WINDOW_NORMAL);imshow(垂直边缘, dst2);cout ?? endl;/*Mat shdjk;cv::threshold(dst2, shdjk, 25, 255, cv::THRESH_BINARY);cv::namedWindow(二值化1212, CV_WINDOW_NORMAL);imshow(二值化1212, shdjk);*///获取结构cv::Mat element1 cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));Mat out1;//进行形态学开运算操作 morphologyEx(dst2, out1, MORPH_OPEN, element1);//形态学开运算cv::namedWindow(xingtai, CV_WINDOW_NORMAL);imshow(xingtai, out1);Mat out2;//第二次进行形态学操作edge_Prewitt(out1, dst1, out1, dst3, dst4, dst, CV_32F);cv::namedWindow(垂直边缘1, CV_WINDOW_NORMAL);imshow(垂直边缘1, out1);cout ?? endl;/*morphologyEx(out1, out1, MORPH_OPEN, element1);//形态学开运算cv::namedWindow(xingtai1, CV_WINDOW_NORMAL);imshow(xingtai1, out1);//获取结构cv::Mat element2 cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(10, 10));//进行形态学闭运算操作 morphologyEx(out1, out2, MORPH_CLOSE, element2);//形态学闭合运算cv::namedWindow(xingtai2, CV_WINDOW_NORMAL);imshow(xingtai2, out2);imwrite(xingtai2.jpg, out2);waitKey(0);*/std::vectorstd::vectorcv::Point contours;std::vectorcv::Vec4i hierarchy;findContours(out1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);double maxArea 0;int index 0;vectorcv::Point maxContour;for (size_t i 0; i contours.size(); i){double area cv::contourArea(contours[i]);if (area maxArea){maxArea area;maxContour contours[i];index i;}}drawContours(src1, contours, index, Scalar(255)); // 参数cv::namedWindow(test, CV_WINDOW_NORMAL);imshow(test, src1);waitKey(0);/*Mat shdjk;cv::threshold(out1, shdjk, 10, 255, cv::THRESH_BINARY);cv::namedWindow(二值化1212, CV_WINDOW_NORMAL);imshow(二值化1212, shdjk);std::vectorstd::vectorcv::Point contours;std::vectorcv::Vec4i hierarchy;cv::findContours(shdjk, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); //只找最外层轮廓std::vectorstd::vectorcv::Point approxCurves(contours.size());for (int i 0; i contours.size(); i) { //绘制逼近后的轮廓double epsilon 0.1 * cv::arcLength(contours[i], true);cv::approxPolyDP(contours[i], approxCurves[i], epsilon, true);cv::drawContours(src1, approxCurves, i, cv::Scalar(0, 255, 0), 2);}cv::namedWindow(success, CV_WINDOW_NORMAL);imshow(success, src1);cv::waitKey();*////*Mat dhfjua;cv::threshold(out2, dhfjua, 15, 255, cv::THRESH_BINARY);cv::namedWindow(二值化000, CV_WINDOW_NORMAL);imshow(二值化000, dhfjua);*//*//膨胀运算将细小缝隙填补上,非必要Mat kernel getStructuringElement(0, Size(3, 3));dilate(out2, dst2, kernel);cv::namedWindow(膨胀, CV_WINDOW_NORMAL);imshow(膨胀, dst2);*//*0cv::threshold(out2, dst2, 5, 255, cv::THRESH_BINARY);cv::namedWindow(二值化, CV_WINDOW_NORMAL);imshow(二值化, dst2);cv::threshold(dst2, dst2, 5, 255, cv::THRESH_BINARY_INV);cv::namedWindow(反二值化, CV_WINDOW_NORMAL);imshow(反二值化, dst2);*//*Mat out3;//进行形态学闭运算操作 morphologyEx(dst2, out3, MORPH_CLOSE, element2);//形态学开运算cv::namedWindow(xingtai3, CV_WINDOW_NORMAL);imshow(xingtai3, out3);imwrite(xingtai3.jpg, out3);*/waitKey(0);vectorVec4i lines;HoughLinesP(src1, lines, 1, CV_PI / 180, 100, 400, 30);int Length[1000] { 0 };//存放直线长度for (size_t i 0; i lines.size(); i){Vec4i I lines[i];double x1 I[0];double y1 I[1];double x2 I[2];double y2 I[3];//筛选满足条件的点if (abs(x1 - x2) abs(y1 - y2) 50){Length[i] sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2));//将满足条件的点画出line(src1, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);cout ( x1 , y1 ) ( x2 , y2 ) endl;//line(canny, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);}}Mat imgShow;imgShow src1;resize(imgShow, imgShow, Size(imgShow.cols / 4, imgShow.rows / 4));imshow(imgShow, imgShow);imwrite(shuchu.png, src1);reserve(Length, 1000);for (int i 0; i 1000; i) {cout 长度 Length[i] endl; //输出排序后的数组元素}for (size_t i 0; i lines.size(); i){Vec4i I lines[i];double x1 I[0];double y1 I[1];double x2 I[2];double y2 I[3];cout sdjk endl;cout int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) endl;//筛选满足条件的点if ((int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) Length[0]) || (int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) Length[1])){//将满足条件的点画出line(src2, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);cout djfkljsa ( x1 , y1 ) ( x2 , y2 ) endl;//line(canny, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);}}imgShow src2;resize(imgShow, imgShow, Size(imgShow.cols / 4, imgShow.rows / 4));imshow(imgShow2, imgShow);imwrite(shuchu2.png, src2);waitKey(0);return 0; } 效果还是不好问题就是出在了相应的一个二值化的过程因此想到使用区域增长算法改进 #include iostream #include string #include list #include vector #include map #include stack #include opencv2/core/core.hpp #include opencv2/highgui/highgui.hpp #include opencv2/imgproc/imgproc.hppusing namespace std; using namespace cv;//------------------------------【两步法新改进版】---------------------------------------------- // 对二值图像进行连通区域标记,从1开始标号 void Two_PassNew(const Mat bwImg, Mat labImg) {assert(bwImg.type() CV_8UC1);labImg.create(bwImg.size(), CV_32SC1); //bwImg.convertTo( labImg, CV_32SC1 );labImg Scalar(0);labImg.setTo(Scalar(1), bwImg);assert(labImg.isContinuous());const int Rows bwImg.rows - 1, Cols bwImg.cols - 1;int label 1;vectorint labelSet;labelSet.push_back(0);labelSet.push_back(1);//the first passint *data_prev (int*)labImg.data; //0-th row : int* data_prev labImg.ptrint(i-1);int *data_cur (int*)(labImg.data labImg.step); //1-st row : int* data_cur labImg.ptrint(i);for (int i 1; i Rows; i){data_cur;data_prev;for (int j 1; j Cols; j, data_cur, data_prev){if (*data_cur ! 1)continue;int left *(data_cur - 1);int up *data_prev;int neighborLabels[2];int cnt 0;if (left 1)neighborLabels[cnt] left;if (up 1)neighborLabels[cnt] up;if (!cnt){labelSet.push_back(label);labelSet[label] label;*data_cur label;continue;}int smallestLabel neighborLabels[0];if (cnt 2 neighborLabels[1] smallestLabel)smallestLabel neighborLabels[1];*data_cur smallestLabel;// 保存最小等价表for (int k 0; k cnt; k){int tempLabel neighborLabels[k];int oldSmallestLabel labelSet[tempLabel]; //这里的不是取地址符号,而是引用符号if (oldSmallestLabel smallestLabel){labelSet[oldSmallestLabel] smallestLabel;oldSmallestLabel smallestLabel;}else if (oldSmallestLabel smallestLabel)labelSet[smallestLabel] oldSmallestLabel;}}data_cur;data_prev;}//更新等价队列表,将最小标号给重复区域for (size_t i 2; i labelSet.size(); i){int curLabel labelSet[i];int prelabel labelSet[curLabel];while (prelabel ! curLabel){curLabel prelabel;prelabel labelSet[prelabel];}labelSet[i] curLabel;}//second passdata_cur (int*)labImg.data;for (int i 0; i Rows; i){for (int j 0; j bwImg.cols - 1; j, data_cur)*data_cur labelSet[*data_cur];data_cur;} }//-------------------------------【老版两步法】------------------------------------------- void Two_PassOld(const cv::Mat _binImg, cv::Mat _lableImg) {//connected component analysis (4-component)//use two-pass algorithm//1. first pass: label each foreground pixel with a label//2. second pass: visit each labeled pixel and merge neighbor label////foreground pixel: _binImg(x,y) 1//background pixel: _binImg(x,y) 0if (_binImg.empty() || _binImg.type() ! CV_8UC1){return;}// 1. first pass_lableImg.release();_binImg.convertTo(_lableImg, CV_32SC1);int label 1; // start by 2std::vectorint labelSet;labelSet.push_back(0); //background: 0labelSet.push_back(1); //foreground: 1int rows _binImg.rows - 1;int cols _binImg.cols - 1;for (int i 1; i rows; i){int* data_preRow _lableImg.ptrint(i - 1);int* data_curRow _lableImg.ptrint(i);for (int j 1; j cols; j){if (data_curRow[j] 1){std::vectorint neighborLabels;neighborLabels.reserve(2); //reserve(n) 预分配n个元素的存储空间int leftPixel data_curRow[j - 1];int upPixel data_preRow[j];if (leftPixel 1){neighborLabels.push_back(leftPixel);}if (upPixel 1){neighborLabels.push_back(upPixel);}if (neighborLabels.empty()){labelSet.push_back(label); //assign to a new labeldata_curRow[j] label;labelSet[label] label;}else{std::sort(neighborLabels.begin(), neighborLabels.end());int smallestLabel neighborLabels[0];data_curRow[j] smallestLabel;//save equivalencefor (size_t k 1; k neighborLabels.size(); k){int tempLabel neighborLabels[k];int oldSmallestLabel labelSet[tempLabel];if (oldSmallestLabel smallestLabel){labelSet[oldSmallestLabel] smallestLabel;oldSmallestLabel smallestLabel;}else if (oldSmallestLabel smallestLabel){labelSet[smallestLabel] oldSmallestLabel;}}}}}}//update equivalent labels//assigned with the smallest label in each equivalent label setfor (size_t i 2; i labelSet.size(); i){int curLabel labelSet[i];int prelabel labelSet[curLabel];while (prelabel ! curLabel){curLabel prelabel;prelabel labelSet[prelabel];}labelSet[i] curLabel;}//2. second passfor (int i 0; i rows; i){int *data _lableImg.ptrint(i);for (int j 0; j cols; j){int pixelLabel data[j];pixelLabel labelSet[pixelLabel];}} }//---------------------------------【种子填充法老版】------------------------------- void SeedFillOld(const cv::Mat binImg, cv::Mat lableImg) //种子填充法 {// 4邻接方法if (binImg.empty() ||binImg.type() ! CV_8UC1){return;}lableImg.release();binImg.convertTo(lableImg, CV_32SC1);int label 1;int rows binImg.rows - 1;int cols binImg.cols - 1;for (int i 1; i rows - 1; i){int* data lableImg.ptrint(i);for (int j 1; j cols - 1; j){if (data[j] 1){std::stackstd::pairint, int neighborPixels;neighborPixels.push(std::pairint, int(i, j)); // 像素位置: i,jlabel; // 没有重复的团开始新的标签while (!neighborPixels.empty()){std::pairint, int curPixel neighborPixels.top(); //如果与上一行中一个团有重合区域则将上一行的那个团的标号赋给它int curX curPixel.first;int curY curPixel.second;lableImg.atint(curX, curY) label;neighborPixels.pop();if (lableImg.atint(curX, curY - 1) 1){//左边neighborPixels.push(std::pairint, int(curX, curY - 1));}if (lableImg.atint(curX, curY 1) 1){// 右边neighborPixels.push(std::pairint, int(curX, curY 1));}if (lableImg.atint(curX - 1, curY) 1){// 上边neighborPixels.push(std::pairint, int(curX - 1, curY));}if (lableImg.atint(curX 1, curY) 1){// 下边neighborPixels.push(std::pairint, int(curX 1, curY));}}}}}}//-------------------------------------------【种子填充法新版】--------------------------- void SeedFillNew(const cv::Mat _binImg, cv::Mat _lableImg) {// connected component analysis(4-component)// use seed filling algorithm// 1. begin with a forgeground pixel and push its forground neighbors into a stack;// 2. pop the pop pixel on the stack and label it with the same label until the stack is empty// // forground pixel: _binImg(x,y)1// background pixel: _binImg(x,y) 0if (_binImg.empty() ||_binImg.type() ! CV_8UC1){return;}_lableImg.release();_binImg.convertTo(_lableImg, CV_32SC1);int label 0; //start by 1int rows _binImg.rows;int cols _binImg.cols;Mat mask(rows, cols, CV_8UC1);mask.setTo(0);int *lableptr;for (int i 0; i rows; i){int* data _lableImg.ptrint(i);uchar *masKptr mask.ptruchar(i);for (int j 0; j cols; j){if (data[j] 255 mask.atuchar(i, j) ! 1){mask.atuchar(i, j) 1;std::stackstd::pairint, int neighborPixels;neighborPixels.push(std::pairint, int(i, j)); // pixel position: i,jlabel; //begin with a new labelwhile (!neighborPixels.empty()){//get the top pixel on the stack and label it with the same labelstd::pairint, int curPixel neighborPixels.top();int curY curPixel.first;int curX curPixel.second;_lableImg.atint(curY, curX) label;//pop the top pixelneighborPixels.pop();//push the 4-neighbors(foreground pixels)if (curX - 1 0){if (_lableImg.atint(curY, curX - 1) 255 mask.atuchar(curY, curX - 1) ! 1) //leftpixel{neighborPixels.push(std::pairint, int(curY, curX - 1));mask.atuchar(curY, curX - 1) 1;}}if (curX 1 cols - 1){if (_lableImg.atint(curY, curX 1) 255 mask.atuchar(curY, curX 1) ! 1)// right pixel{neighborPixels.push(std::pairint, int(curY, curX 1));mask.atuchar(curY, curX 1) 1;}}if (curY - 1 0){if (_lableImg.atint(curY - 1, curX) 255 mask.atuchar(curY - 1, curX) ! 1)// up pixel{neighborPixels.push(std::pairint, int(curY - 1, curX));mask.atuchar(curY - 1, curX) 1;}}if (curY 1 rows - 1){if (_lableImg.atint(curY 1, curX) 255 mask.atuchar(curY 1, curX) ! 1)//down pixel{neighborPixels.push(std::pairint, int(curY 1, curX));mask.atuchar(curY 1, curX) 1;}}}}}} }//---------------------------------【颜色标记程序】----------------------------------- //彩色显示 cv::Scalar GetRandomColor() {uchar r 255 * (rand() / (1.0 RAND_MAX));uchar g 255 * (rand() / (1.0 RAND_MAX));uchar b 255 * (rand() / (1.0 RAND_MAX));return cv::Scalar(b, g, r); }void LabelColor(const cv::Mat labelImg, cv::Mat colorLabelImg) {int num 0;if (labelImg.empty() ||labelImg.type() ! CV_32SC1){return;}std::mapint, cv::Scalar colors;int rows labelImg.rows;int cols labelImg.cols;colorLabelImg.release();colorLabelImg.create(rows, cols, CV_8UC3);colorLabelImg cv::Scalar::all(0);for (int i 0; i rows; i){const int* data_src (int*)labelImg.ptrint(i);uchar* data_dst colorLabelImg.ptruchar(i);for (int j 0; j cols; j){int pixelValue data_src[j];if (pixelValue 1){if (colors.count(pixelValue) 0){colors[pixelValue] GetRandomColor();num;}cv::Scalar color colors[pixelValue];*data_dst color[0];*data_dst color[1];*data_dst color[2];}else{data_dst;data_dst;data_dst;}}}printf(color num : %d \n, num); }//------------------------------------------【测试主程序】------------------------------------- int main() {cv::Mat binImage cv::imread(sda.jpg, 0);//cv::threshold(binImage, binImage, 50, 1, CV_THRESH_BINARY);cv::Mat labelImg;double time;time getTickCount();SeedFillNew(binImage, labelImg);time 1000 * ((double)getTickCount() - time) / getTickFrequency();cout std::fixed time ms endl;//彩色显示/*cv::Mat colorLabelImg;LabelColor(labelImg, colorLabelImg);cv::imshow(colorImg, colorLabelImg);*///灰度显示cv::Mat grayImg;labelImg * 10;labelImg.convertTo(grayImg, CV_8UC1);cv::imshow(labelImg, grayImg);double minval, maxval;minMaxLoc(labelImg, minval, maxval);cout minval minval endl;cout maxval maxval endl;cv::waitKey(0);return 0; } 终于知道是啥原因了我在进行Prewitt算子对边缘进行粗定位检测过后没有进行去噪处理一定要把图像转换为二值图像就方便多了。并且还要记住霍夫检测的直线像素是255白线才可以经过长时间的试错终于解决了。输入原图像如下所示我这里使用的去噪对比了四种但是下面这种是最好的。Opencv 非局部降噪_51CTO博客_opencv降噪Opencv 非局部降噪opencv自带的非局部降噪算法CV_EXPORTS_WvoidfastNlMeansDenoising(InputArraysrc,OutputArraydst,floath3,inttemplateWindowSize7,intsearchWindowSize21);h是过滤强度templateWindowSize是分块大小searchWindowSize是搜索区域大小。应用实例intmain(){MatI..https://blog.51cto.com/u_15458280/4843576 #includeopencv2/opencv.hpp #includeiostream using namespace std; using namespace cv;//数组从大到小排序 void reserve(int x[], int n) {int i, j, temp;for (i 0; i n - 1; i) { //一共n个元素则需要比较n-1次for (j 0; j n - 1 - i; j) { //每一个元素需要比较的次数if (x[i] x[i j 1]) {temp x[i];x[i] x[i j 1];x[i j 1] temp;}}} }void add_salt_pepper_noise(Mat image) {RNG rng(12345);int h image.rows;int w image.cols;int nums 10000;for (int i 0; i nums; i) {int x rng.uniform(0, w);int y rng.uniform(0, h);if (i % 2 1) {image.atVec3b(y, x) Vec3b(255, 255, 255);}else {image.atVec3b(y, x) Vec3b(0, 0, 0);}}imshow(salt pepper, image); }void gaussian_noise(Mat image) {Mat noise Mat::zeros(image.size(), image.type());randn(noise, (15, 15, 15), (30, 30, 30));Mat dst;add(image, noise, dst);imshow(gaussian noise, dst);dst.copyTo(image); }Mat convertTo3Channels(const Mat binImg) {Mat three_channel Mat::zeros(binImg.rows, binImg.cols, CV_8UC3);vectorMat channels;for (int i 0; i 3; i){channels.push_back(binImg);}merge(channels, three_channel);return three_channel; }int main(int argc, char*argv[]) {//加载图像Mat img, gray_image, dst;img imread(垂直边缘.jpg);Mat img1 imread(垂直边缘.jpg);//判断图像是否导入成功if (img.empty()){cout 加载失败 endl;return -1;}//显示图像namedWindow(original image, WINDOW_AUTOSIZE);imshow(original image, img);//转换灰度图像cvtColor(img, gray_image, COLOR_BGR2GRAY);//获取灰度图像宽度和高度int width gray_image.cols;int height gray_image.rows;//遍历像素值(单通道)for (int row 0; row height; row){for (int col 0; col width; col){int gray gray_image.atuchar(row, col);gray_image.atuchar(row, col) 255 - gray; //图像取反};};namedWindow(inv_gray_image, WINDOW_AUTOSIZE);imshow(inv_gray_image, gray_image);Mat sh;fastNlMeansDenoising(gray_image, sh, 21, 7, 21);namedWindow(inv_gray_image1, WINDOW_AUTOSIZE);imshow(inv_gray_image1, sh);waitKey(50);//Mat s;//获取灰度图像宽度和高度width sh.cols;height sh.rows;//遍历像素值(单通道)for (int row 0; row height; row){for (int col 0; col width; col){int gray sh.atuchar(row, col);sh.atuchar(row, col) 255 - gray; //图像取反};};namedWindow(inv_gray_image2, WINDOW_AUTOSIZE);imshow(inv_gray_image2, sh);cv::threshold(sh, sh, 50, 255, cv::THRESH_BINARY);cv::namedWindow(二值化, CV_WINDOW_NORMAL);imshow(二值化, sh);vectorVec4i lines;HoughLinesP(sh, lines, 1, CV_PI / 180, 50,100, 5);int Length[100] { 0 };//存放直线长度for (size_t i 0; i lines.size(); i){Vec4i I lines[i];double x1 I[0];double y1 I[1];double x2 I[2];double y2 I[3];//筛选满足条件的点if (abs(x1 - x2) abs(y1 - y2) 50){Length[i] sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2));//将满足条件的点画出line(img, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);cout ( x1 , y1 ) ( x2 , y2 ) endl;//line(canny, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);}}Mat imgShow;imgShow img;resize(imgShow, imgShow, Size(imgShow.cols / 4, imgShow.rows / 4));imshow(imgShow, imgShow);imwrite(shuchu.png, imgShow);reserve(Length, 100);for (int i 0; i 100; i) {cout 长度 Length[i] endl; //输出排序后的数组元素}for (size_t i 0; i lines.size(); i){Vec4i I lines[i];double x1 I[0];double y1 I[1];double x2 I[2];double y2 I[3];cout sdjk endl;cout int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) endl;//筛选满足条件的点if ((int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) Length[0]) || (int(sqrt((x1 - x2)*(x1 - x2) (y1 - y2) * (y1 - y2))) Length[1])){//将满足条件的点画出line(img1, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);cout djfkljsa ( x1 , y1 ) ( x2 , y2 ) endl;//line(canny, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);}}imgShow img1;resize(imgShow, imgShow, Size(imgShow.cols / 4, imgShow.rows / 4));imshow(imgShow2, imgShow);imwrite(shuchu2.png, imgShow);waitKey(0);return 0; }; 结果图如下所示 ​​​​​​​ 终于弄出来了去干饭。
http://www.hkea.cn/news/14282091/

相关文章:

  • 网站设置子目录开发商城系统app
  • 查找网站建设历史记录基金管理公司司网站建设要求
  • 上海企业网页制作seo原创工具
  • 企业网站网页打开慢建设游戏网站
  • zencart网站建设wordpress 搜索关键词
  • 做手机网站优长沙推广引流
  • 个人接做网站多少钱江西城开建设集团有限公司网站
  • 衡水做网站的地方定制平台
  • 陕西住房和城乡建设部网站深圳总部企业名单
  • 网站建设服务费开票成都旅游攻略四天三夜
  • 网站建设攻略微网站建设微网站建设
  • 西安企业网站建设代理机构赣州做网站推广
  • 学校门户网站建设个人养老保险怎么缴纳
  • com网站免费注册沈阳制作网站
  • 网站优化seo四个建议com网站建设中
  • 网站制作外包价格石家庄发布最新公告
  • 网站注册登录大型网站的技术架构问题
  • 2017两学一做网站广州网站建设广州网络推广公司好
  • 网站竞价推广做网站用哪种语言好
  • 安阳汤阴县网站建设公司网站的关键词推广怎么做
  • 编程网站scratch网址opencart做外贸网站怎样
  • 网站开发的在线支付功能郑州网站制作方案报价
  • 杭州建设企业网站的wordpress 增加文章字段
  • 迎中国建设银行网站国美在线网站建设
  • 网站制作的文章创建商城
  • 重庆sem网站推广台州网络推广
  • 网站分成推广怎么做有人知道做网站吗
  • 网站建设+青海茌平微网站建设
  • 羽毛球网站建设网站备案的网站名
  • 网站的构建是怎样的长春做网站seo