基于梯度方向、极化变换和聚类算法的图像主特征直线检测
生活随笔
收集整理的這篇文章主要介紹了
基于梯度方向、极化变换和聚类算法的图像主特征直线检测
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基于梯度方向、極化變換和聚類算法的圖像主特征直線檢測
基于機器學習和圖像處理的直線檢測
代碼主要思路:
1)借助類LSD直線檢測,提取圖像各個方向梯度;2)對像素中的各個梯度方向做極化變換;3)對計劃變換后的結果進行聚類運算;4)對聚類運算結果,選取topK,進行極化反變換;5)對結果進行腐蝕+膨脹+濾波,進行結果整合;6)可根據圖像的長度、斜率等進行配置篩選和去重。
代碼結果以及下載地址:下載地址
主函數代碼
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include <vector>
#include "lsd.h"
#include <fstream>
#include <math.h>
#include <algorithm>
#include <Cstring>
#include <io.h>
#include<numeric>
#define PI 3.1415926using namespace std;
using namespace cv;typedef struct {image_double imgDouble;Mat imgSrc, imgPro;
}imageInfo;void listFiles(const char * dir);
imageInfo imageProcess(char * DIR, double scale);
int lineLengthThreshold(ntuple_list LS, double scale);
vector<float> getPolarLine(vector<float> p);
void connectLine(Mat imgPlot, vector<float> decarTopX0, vector<float> decarTopY0, vector<float> decarTopX1, vector<float> decarTopY1);
void HighPassFilterSobel(const Mat& image, Mat& result);void main()
{//生成圖像索引char dir[20] = "images\\";listFiles(dir);ifstream imageIndex;imageIndex.open("imageIndex.txt");const int LINE = 200;char str[LINE];while (imageIndex.getline(str, LINE)) {char DIR[260] = "images\\";strcat_s(DIR, str);double scale = 0.8;imageInfo imgInfo = imageProcess(DIR, scale);image_double image = imgInfo.imgDouble;Mat img = imgInfo.imgPro;Mat imgPlot = imgInfo.imgSrc;imshow("imgPlot", imgPlot);ntuple_list ls0 = lsd(image);cout << "ls0->size:" << ls0->size << endl;int binNum = 60;vector<double> disNum(binNum, 0);double binLength = img.rows / binNum;//設置直線篩選長度int lineThreshold = lineLengthThreshold(ls0, scale);cout << "lineThreshold:" << lineThreshold << endl;//將笛卡爾坐標系點轉到極坐標系vector<float> polarR, polarTheta, decarPointLocX0, decarPointLocY0, decarPointLocX1, decarPointLocY1;vector<float> indexStep;//記錄累加的步長for (int i = 0; i < ls0->size; i++) {ls0->values[5 * i + 0] = (int)(ls0->values[5 * i + 0] / scale);ls0->values[5 * i + 1] = (int)(ls0->values[5 * i + 1] / scale);ls0->values[5 * i + 2] = (int)(ls0->values[5 * i + 2] / scale);ls0->values[5 * i + 3] = (int)(ls0->values[5 * i + 3] / scale);int x0 = ls0->values[5 * i + 0];int y0 = ls0->values[5 * i + 1];int x1 = ls0->values[5 * i + 2];int y1 = ls0->values[5 * i + 3];//線長篩選并記錄float lineLength = sqrt((x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0));if (lineLength < lineThreshold) {continue;}//邊緣篩選int xTemp = img.cols - 10;int yTemp = img.rows - 10;if ((x0 < 10 && x1 < 10) || (x0 > xTemp && x1 > xTemp) || (y0 < 10 && y1 < 10) || (y0 > yTemp && y1 > yTemp)) {continue;}Point pp0 = Point(x0, y0);Point pp1 = Point(x1, y1);line(img, pp0, pp1, Scalar(225, 0, 0), 2, 4);circle(img, pp0, 10, Scalar(0, 0, 0));circle(img, pp1, 10, Scalar(255, 255, 255));float tempIndexStep = lineLength / lineThreshold;//cout << "indexStep:" << tempIndexStep << endl;indexStep.push_back(tempIndexStep);decarPointLocX0.push_back(x0);decarPointLocY0.push_back(y0);decarPointLocX1.push_back(x1);decarPointLocY1.push_back(y1);//統一坐標系并記錄vector<float> decarPoint;int x0Point = x0 - img.cols / 2;int y0Point = img.rows / 2 - y0;int x1Point = x1 - img.cols / 2;int y1Point = img.rows / 2 - y1;decarPoint.push_back(x0Point);decarPoint.push_back(y0Point);decarPoint.push_back(x1Point);decarPoint.push_back(y1Point);//獲取極坐標并記錄vector<float> polarPoint = getPolarLine(decarPoint);polarR.push_back(polarPoint[0]);polarTheta.push_back(polarPoint[1]);}float rThreshold = 15;float thetaThreshold = 0.1;//尋找各個值的聚類統計數量int totalLine = polarR.size();cout << "totalLine:" << totalLine << endl;vector<float> index(totalLine, 0);for (int i = 0; i < totalLine; i++) {for (int j = 0; j < totalLine; j++) {if (i == j) {continue;}float subpolarR = abs(polarR[i] - polarR[j]);float subpolarTheta = abs(polarTheta[i] - polarTheta[j]);if (subpolarR < rThreshold && subpolarTheta < thetaThreshold) {if (indexStep[j] != 0)index[i] = index[i] + indexStep[j];elseindex[i]++;}}}//尋找聚類區域最多的點的索引TOP1vector<float>::iterator maxIndex = max_element(index.begin(), index.end());cout << "------------------------------" << endl;cout << "max:" << *maxIndex << endl;int maxInd = distance(index.begin(), maxIndex);cout << "maxInd:" << maxInd << endl;//存儲聚類最多點的坐標并畫線TOP1vector<float> decarTop1X0, decarTop1Y0, decarTop1X1, decarTop1Y1;vector<int> setLabel(totalLine, 0);//0:該點未使用;1:該點已使用for (int i = 0; i < totalLine; i++) {float subpolarR = abs(polarR[i] - polarR[maxInd]);float subpolarTheta = abs(polarTheta[i] - polarTheta[maxInd]);if (subpolarR < rThreshold && subpolarTheta < thetaThreshold) {decarTop1X0.push_back(decarPointLocX0[i]);decarTop1Y0.push_back(decarPointLocY0[i]);decarTop1X1.push_back(decarPointLocX1[i]);decarTop1Y1.push_back(decarPointLocY1[i]);setLabel[i] = 1;Point pp0 = Point(decarPointLocX0[i], decarPointLocY0[i]);Point pp1 = Point(decarPointLocX1[i], decarPointLocY1[i]);//line(imgPlot, pp0, pp1, Scalar(255, 0, 0), 3, 4);}}connectLine(imgPlot, decarTop1X0, decarTop1Y0, decarTop1X1, decarTop1Y1);//尋找聚類區域第二多的點的索引TOP2int usedPointTop2 = 0;vector<float> secondIndex(totalLine, 0);//剔除第一大的元素后的存儲位置for (int i = 0; i < totalLine; i++) {if (setLabel[i] == 0) {secondIndex[i] = index[i];usedPointTop2++;}elsesecondIndex[i] = 0;//cout << secondIndex[i] << "-";}if (usedPointTop2 < 4) {continue;}//cout << endl;vector<float>::iterator secondMaxIndex = max_element(secondIndex.begin(), secondIndex.end());cout << "------------------------------" << endl;cout << "secondMax:" << *secondMaxIndex << endl;int secondMaxInd = distance(secondIndex.begin(), secondMaxIndex);cout << "secondMaxInd:" << secondMaxInd << endl;//存儲聚類第二多點的坐標并畫線TOP2vector<float> decarTop2X0, decarTop2Y0, decarTop2X1, decarTop2Y1;for (int i = 0; i < totalLine; i++) {float subpolarR = abs(polarR[i] - polarR[secondMaxInd]);float subpolarTheta = abs(polarTheta[i] - polarTheta[secondMaxInd]);if (subpolarR < rThreshold && subpolarTheta < thetaThreshold && setLabel[i] == 0) {decarTop2X0.push_back(decarPointLocX0[i]);decarTop2Y0.push_back(decarPointLocY0[i]);decarTop2X1.push_back(decarPointLocX1[i]);decarTop2Y1.push_back(decarPointLocY1[i]);Point pp0 = Point(decarPointLocX0[i], decarPointLocY0[i]);Point pp1 = Point(decarPointLocX1[i], decarPointLocY1[i]);setLabel[i] = 1;//line(imgPlot, pp0, pp1, Scalar(0, 255, 0), 3, 4);}}connectLine(imgPlot, decarTop2X0, decarTop2Y0, decarTop2X1, decarTop2Y1);//尋找聚類區域第三多的點的索引TOP3int usedPointTop3 = 0;vector<float> thirdIndex(totalLine, 0);//剔除第一大和第二大的元素后的存儲位置for (int i = 0; i < totalLine; i++) {if (setLabel[i] == 0) {thirdIndex[i] = secondIndex[i];usedPointTop3++;}elsethirdIndex[i] = 0;//cout << thirdIndex[i] << "-";}//cout << endl;if (usedPointTop3 < 4) {continue;}vector<float>::iterator thirdMaxIndex = max_element(thirdIndex.begin(), thirdIndex.end());cout << "------------------------------" << endl;cout << "thirdMax:" << *thirdMaxIndex << endl;int thirdMaxInd = distance(thirdIndex.begin(), thirdMaxIndex);cout << "thirdMaxInd:" << thirdMaxInd << endl;//存儲聚類第三多點的坐標并畫線TOP3vector<float> decarTop3X0, decarTop3Y0, decarTop3X1, decarTop3Y1;for (int i = 0; i < totalLine; i++) {float subpolarR = abs(polarR[i] - polarR[thirdMaxInd]);float subpolarTheta = abs(polarTheta[i] - polarTheta[thirdMaxInd]);if (subpolarR < rThreshold && subpolarTheta < thetaThreshold && setLabel[i] == 0) {decarTop3X0.push_back(decarPointLocX0[i]);decarTop3Y0.push_back(decarPointLocY0[i]);decarTop3X1.push_back(decarPointLocX1[i]);decarTop3Y1.push_back(decarPointLocY1[i]);Point pp0 = Point(decarPointLocX0[i], decarPointLocY0[i]);Point pp1 = Point(decarPointLocX1[i], decarPointLocY1[i]);setLabel[i] = 1;//line(imgPlot, pp0, pp1, Scalar(0, 0, 255), 3, 4);}}connectLine(imgPlot, decarTop3X0, decarTop3Y0, decarTop3X1, decarTop3Y1);//尋找聚類區域第四多的點的索引TOP4int usedPointTop4 = 0;vector<float> fourthIndex(totalLine, 0);//剔除第一大的元素后的存儲位置for (int i = 0; i < totalLine; i++) {if (setLabel[i] == 0) {fourthIndex[i] = thirdIndex[i];usedPointTop4++;}elsefourthIndex[i] = 0;//cout << fourthIndex[i] << "-";}//cout << endl;vector<float>::iterator fourthMaxIndex = max_element(fourthIndex.begin(), fourthIndex.end());cout << "------------------------------" << endl;cout << "fourthMax:" << *fourthMaxIndex << endl;int fourthMaxInd = distance(fourthIndex.begin(), fourthMaxIndex);cout << "fourthMaxInd:" << fourthMaxInd << endl;if (usedPointTop4 < 4 || *fourthMaxIndex == 0) {continue;}//存儲聚類第四多點的坐標并畫線TOP4vector<float> decarTop4X0, decarTop4Y0, decarTop4X1, decarTop4Y1;for (int i = 0; i < totalLine; i++) {float subpolarR = abs(polarR[i] - polarR[fourthMaxInd]);float subpolarTheta = abs(polarTheta[i] - polarTheta[fourthMaxInd]);if (subpolarR < rThreshold && subpolarTheta < thetaThreshold && setLabel[i] == 0) {decarTop4X0.push_back(decarPointLocX0[i]);decarTop4Y0.push_back(decarPointLocY0[i]);decarTop4X1.push_back(decarPointLocX1[i]);decarTop4Y1.push_back(decarPointLocY1[i]);Point pp0 = Point(decarPointLocX0[i], decarPointLocY0[i]);Point pp1 = Point(decarPointLocX1[i], decarPointLocY1[i]);setLabel[i] = 1;//line(img, pp0, pp1, Scalar(0, 255, 255), 3, 4);}}connectLine(img, decarTop4X0, decarTop4Y0, decarTop4X1, decarTop4Y1);//尋找聚類區域第五多的點的索引TOP5int usedPointTop5 = 0;vector<float> fifthIndex(totalLine, 0);//剔除第一大的元素后的存儲位置for (int i = 0; i < totalLine; i++) {if (setLabel[i] == 0) {fifthIndex[i] = fourthIndex[i];usedPointTop5++;}elsefifthIndex[i] = 0;//cout << fifthIndex[i] << "-";}//cout << endl;vector<float>::iterator fifthMaxIndex = max_element(fifthIndex.begin(), fifthIndex.end());cout << "------------------------------" << endl;cout << "fifthMax:" << *fifthMaxIndex << endl;int fifthMaxInd = distance(fifthIndex.begin(), fifthMaxIndex);cout << "fifthMaxInd:" << fifthMaxInd << endl;if (usedPointTop5 < 4 || *fifthMaxIndex == 0) {continue;}//存儲聚類第五多點的坐標并畫線TOP5vector<float> decarTop5X0, decarTop5Y0, decarTop5X1, decarTop5Y1;for (int i = 0; i < totalLine; i++) {float subpolarR = abs(polarR[i] - polarR[fifthMaxInd]);float subpolarTheta = abs(polarTheta[i] - polarTheta[fifthMaxInd]);if (subpolarR < rThreshold && subpolarTheta < thetaThreshold && setLabel[i] == 0) {decarTop5X0.push_back(decarPointLocX0[i]);decarTop5Y0.push_back(decarPointLocY0[i]);decarTop5X1.push_back(decarPointLocX1[i]);decarTop5Y1.push_back(decarPointLocY1[i]);Point pp0 = Point(decarPointLocX0[i], decarPointLocY0[i]);Point pp1 = Point(decarPointLocX1[i], decarPointLocY1[i]);setLabel[i] = 1;//line(img, pp0, pp1, Scalar(255, 0, 255), 3, 4);}}connectLine(img, decarTop5X0, decarTop5Y0, decarTop5X1, decarTop5Y1);char resultPath[200] = "resultPath//";strcat_s(resultPath, str);imwrite(resultPath, imgPlot);namedWindow("IMG", CV_WINDOW_AUTOSIZE);//resizeWindow("IMG", 600, 800);imshow("IMG", imgPlot);waitKey(1);}system("Pause");
}
總結
以上是生活随笔為你收集整理的基于梯度方向、极化变换和聚类算法的图像主特征直线检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于深度学习的目标检测综述
- 下一篇: 基于可见光(LIFI)通信系统 的机动车