当前位置:网站首页>The principle of hough transform detection of straight lines (opencv hough straight line detection)
The principle of hough transform detection of straight lines (opencv hough straight line detection)
2022-07-31 15:18:00 【Full stack programmer webmaster】
大家好,又见面了,我是你们的朋友全栈君.
Hough transform of straight lines:
The conversion formula of Hough space polar coordinates and image space: p = y * sin(theta) + x * cos(theta);
Then traverse each coordinate point of the image,Each coordinate point is incremented by one degree,Find the correspondingp值,存入数组中,Find the number in the array that is greater than a certain thresholdp和theta,Then put it in image space 直线 恢复出来
Hough transform is to convert the line segment on the left space of the image to a point in Hough space,Then determine whether it is a line segment by the number of points(But the result drawn is a straight line)
实现代码如下:
#include <iostream>
#include "gdal_priv.h"
#include <string>
using namespace std;
//图像的膨胀
//The implementation of the algorithm still has some repetitions,It will cause a waste of space and time,但是效果还可以,暂定如此,If there is a good algorithm, it will be improved
void Expand(unsigned char* date,unsigned char* ExpandImage,int Width,int Height)
{
int x, y;
int Direction[8][2] = {-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0};
int Index;
for(int i = 1;i < Height - 1;++i)
{
for(int j = 1;j < Width - 1;++j)
{
if(date[i * Width + j] == 255)
{
for(int k = 0;k < 8;++k)
{
x = i + Direction[k][0];
y = j + Direction[k][1];
Index = x * Width + y;
ExpandImage[Index] = 255;
}
}
}
}
return;
}
//图像的腐蚀
void Erosion(unsigned char* date,unsigned char* ErosionImage,int Width,int Height)
{
int x, y;
int Direction[8][2] = {-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0};
int Index;
for(int i = 1;i < Height - 1;++i)
{
for(int j = 1;j < Width - 1;++j)
{
if(date[i * Width + j] == 0)
{
for(int k = 0;k < 8;++k)
{
x = i + Direction[k][0];
y = j + Direction[k][1];
Index = x * Width + y;
ErosionImage[Index] = 0;
}
}
}
}
return;
}
//Image subtraction to find boundaries
void Subtraction(unsigned char* ResultImage,unsigned char* leftImage,unsigned char* rightImage,int Width,int Height)
{
int Index;
for(int i = 0;i < Height;++i)
for(int j = 0;j < Width;++j)
{
Index = i * Width + j;
ResultImage[Index] = leftImage[Index] - rightImage[Index];
}
return ;
}
void FindBoundary(unsigned char* image,unsigned char* tempImage,int Width,int Height)
{
//Generates an image inflated for the image
unsigned char* ExpandImage = new unsigned char[Width * Height];
memset(ExpandImage,0,sizeof(unsigned char) * Width * Height);
Expand(image ,ExpandImage,Width ,Height);
Subtraction(tempImage,ExpandImage,image,Width,Height);
}
/************************************************************************* * 直线的Hough检测 * 参数:image0original graphics,image1为边缘检测结果,w、h为图像的宽和高 * 由于得到的HoughThe transformed image has a different size than the original image,In order to get the new width and height information * w、h使用引用类型 *************************************************************************/
unsigned char** HoughLine(unsigned char* image0, unsigned char* &tempImage, int &Width, int &Height,int scale=1)
{
//Define a table of trigonometric functions
double sinValue[360];
double cosValue[360];
int i,x,y;
int k = 100;
int p = (int)(sqrt((double)(Width * Width + Height * Height) + 1)); //计算对角线长度
//Request temporary storage space Used to save edge detection results
// tempImage = new unsigned char[Width * Height];
memset(tempImage,0,sizeof(unsigned char) * Width * Height);
//边缘检测
// SideGrandiant(image0, tempImage, Width, Height);
FindBoundary(image0, tempImage, Width, Height);
// //根据HoughTransform the size of the resulting graph Re-allocate space for the output image
// if(image1 != NULL)
// delete image1;
//
image1 = (BYTE*)malloc(sizeof(BYTE)*p*360*4);
//
// image1 = new unsigned char[p * 360];
// memset(image1,0,p * 360);
//Convert the image to matrix form
// BYTE** HoughBuf =CreatImage(image1,360,p);
unsigned char** HoughBuf = new unsigned char* [p];
for(int i = 0;i < p;++i)
{
HoughBuf[i] = new unsigned char[360];
memset(HoughBuf[i],0,sizeof(unsigned char) * 360);
//HoughBuf[i] = image1 + i * 360;
}
//for(int i = 0;i < p;++i)
//{
// for(int j = 0;j < 360;++j)
// HoughBuf[i][j] = image1[i * 360 + j];
//}
//Calculate the table of trigonometric functions
for(i=0; i<360 ; i++)
{
sinValue[i] = sin(i*3.1415926/180);
cosValue[i] = cos(i*3.1415926/180);
}
int tp;
//Iterate over each pixel in the original image
for(y = 0; y < Height; y++)
for(x = 0; x < Width; x++)
{
//Detects any straight area that passes through the current pixel
for(i = 0; i < 360; i++)
{
if( tempImage[(y * Width + x)] > k )
{
tp = (int)( x * sinValue[i] + y * cosValue[i]);
//Negative numbers are ignored while preventing counter overflow
if (tp < 0 || HoughBuf[tp][i] == 255) continue;
HoughBuf[tp][i] += scale;
}
}
}
//Resize the image
//Width = 360;
//Height = p;
// delete tempImage;
return HoughBuf;
}
//Draw the detected line
void DrawLine(unsigned char* LineIamge,int Width,int Height,int p,int theta)
{
double k,b;
int x,y;
if(theta != 90) //if the slope exists
{
//Calculate the parameters of the equation of the line
b = p / cos(theta * 3.1415926535 / 180);
k = -sin(theta * 3.1415926535 / 180) / cos(theta * 3.1415926535 / 180);
y=0;
x=0;
//斜率小于1的情况
if(abs(k) <= 1)
{
for(x = 0;x < Width;x++)
{
y=(int)(k * x + b);
if(y >= 0 && y < Height)
{
LineIamge[y * Width + x] = 255;
}
}
}
//斜率大于1的情况
else
{
for(y = 0;y < Height;y++)
{
x = (int)(y / k - b / k);
if(x >= 0 && x < Width)
{
/*imageBuf[y][x*4]=255; imageBuf[y][x*4+1]=0; imageBuf[y][x*4+2]=0; imageBuf[y][x*4+3]=255;*/
LineIamge[y * Width + x] = 255;
}
}
}
}
//斜率不存在的情况
else
{
for(y = 0; y < Height;y++)
{
/*imageBuf[y][p*4]=255; imageBuf[y][p*4+1]=0; imageBuf[y][p*4+2]=0; imageBuf[y][p*4+3]=255;*/
LineIamge[y * Width + p] = 255;
}
}
}
int main()
{
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
string str1="1.1.bmp";
string str2="1.2.tif";
string str3 = "1.3.tif";
GDALDataset* pInDataset=(GDALDataset*)GDALOpen(str1.data() ,GA_ReadOnly);
if(pInDataset == nullptr)
{
cout<<"Input image not found"<<endl;
getchar();
return 1;
}
int Width=pInDataset->GetRasterXSize();
int Height = pInDataset->GetRasterYSize();
int band = pInDataset->GetRasterCount();
double dGeoTrans[6]={};
pInDataset->GetGeoTransform(dGeoTrans);
const char* cProjectionRef = pInDataset->GetProjectionRef();
unsigned char* Image = new unsigned char[Width * Height];
GDALRasterBand* pRasterBand = pInDataset->GetRasterBand(1);
CPLErr err=pRasterBand->RasterIO(GF_Read ,0 ,0 ,Width ,Height ,Image ,Width ,Height ,GDT_Byte ,0,0);
unsigned char* ResultImage = new unsigned char[Width * Height];//Save the edge information of the image,The edge image obtained by subtracting the original image from the dilated image,Used to detect if an edge is obtained
//ResultImage = nullptr;
//unsigned char** HoughBuf = nullptr;
unsigned char** HoughBuf;
HoughBuf = HoughLine(Image,ResultImage,Width,Height);
GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
GDALDataset* pOutDataset = pDriver->Create("1.2.tif" ,Width ,Height ,1 ,GDT_Byte ,NULL);
GDALRasterBand* pOutRasterband=pOutDataset->GetRasterBand(1);
pOutRasterband->RasterIO(GF_Write ,0 ,0 ,Width ,Height ,ResultImage ,Width ,Height ,GDT_Byte ,0 ,0);
int p = (int)(sqrt((double)(Width * Width + Height * Height) + 1)); //计算对角线长度
unsigned char* LineImage = new unsigned char[Width * Height];
memset(LineImage,0,sizeof(unsigned char) * Width * Height);
if(HoughBuf != nullptr)
for(int i = 0;i < p;++i)
{
for(int j = 0;j < 360;++j)
{
if(HoughBuf[i][j] > 200) //设置阈值为200,可自行设置
{
cout<<(int)HoughBuf[i][j]<<" ";
DrawLine(LineImage,Width,Height,i,j);//The result obtained is a straight line
}
}
cout<<"***************"<<endl;
}
GDALDriver* pLineDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
GDALDataset* pOutLineDataset = pLineDriver->Create("1.3.tif" ,Width ,Height ,1 ,GDT_Byte ,NULL);
GDALRasterBand* pOutLineRasterband=pOutLineDataset->GetRasterBand(1);
pOutLineRasterband->RasterIO(GF_Write ,0 ,0 ,Width ,Height ,LineImage ,Width ,Height ,GDT_Byte ,0 ,0);
delete Image;
delete ResultImage;
delete LineImage;
for(int i = 0;i < p;++i)
delete HoughBuf[i];
delete HoughBuf;
GDALClose(pOutDataset);
GDALClose(pInDataset);
GDALClose(pOutLineDataset);
GetGDALDriverManager()->DeregisterDriver(pDriver);
GetGDALDriverManager()->DeregisterDriver(pLineDriver);
system("pause");
return 0;
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/128252.html原文链接:https://javaforall.cn
边栏推荐
- 基于最小二乘法和SVM从天气预报中预测太阳能发电量(Matlab代码实现)
- 为什么黑客领域几乎一片男生?
- 力扣:56. 合并区间
- 三、数组
- The R language ggstatsplot package ggbarstats function visualizes bar charts, and adds hypothesis test results (including sample number, statistics, effect size and its confidence interval, significan
- Ubantu专题4:xshell、xftp连接接虚拟机以及设置xshell复制粘贴快捷键
- JVM参数解析 Xmx、Xms、Xmn、NewRatio、SurvivorRatio、PermSize、PrintGC「建议收藏」
- 腾讯云部署----DevOps
- Excel quickly aligns the middle name of the table (two-word name and three-word name alignment)
- Getting Started with TextBlock Control Basic Tools Usage, Get Started
猜你喜欢
随机推荐
女性服务社群产品设计
TCP详解
名创优品斥资6.95亿购买创始人叶国富所持办公楼股权
Selenium自动化中无头浏览器的应用
AVH Deployment Practice (1) | Deploying the Flying Paddle Model on Arm Virtual Hardware
LeetCode二叉树系列——222.完全二叉树的节点个数
SIGABRT 报错时的注意事项和解决方法
谷歌CTS测试(cta测试)
R language ggplot2 visualization: use the ggboxplot function of the ggpubr package to visualize the box plot, use the font function to customize the font size, color, style (bold, italic) of the legen
国内市场上的BI软件,到底有啥区别
定时器的类型
Kubernetes原理剖析与实战应用手册,太全了
Small test knife: Go reflection helped me convert Excel to Struct
01 邂逅typescript,环境搭建
《微信小程序-进阶篇》Lin-ui组件库源码分析-Icon组件
ES6 类
Bilateral filtering acceleration "recommended collection"
R语言ggplot2可视化:使用ggpubr包的ggmaplot函数可视化MA图(MA-plot)、font.legend参数和font.main参数设置标题和图例字体加粗
Getting started with UnityShader (1) - GPU and Shader
【MySQL】Mysql范式及外键作用