当前位置:网站首页>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
边栏推荐
- 《微信小程序-进阶篇》Lin-ui组件库源码分析-Icon组件
- Doing things software development - the importance of law and understanding of reasonable conclusions
- How useful is four-quadrant time management?
- Introductory UnityShader learning (2) - the rendering pipeline
- 数据表插入数据insert into
- 四象限时间管理有多好用?
- WPF项目--控件入门基础用法,必知必会XAML
- Emmet 语法
- 力扣:714. 买卖股票的最佳时机含手续费
- R语言的画图代码及差异性分析[通俗易懂]
猜你喜欢
随机推荐
WPF项目--控件入门基础用法,必知必会XAML
thread_local 变量的析构顺序
自适应控制——仿真实验三 用超稳定性理论设计模型参考自适应系统
Word表格转到Excel中
R language ggplot2 visualization: use the ggmapplot function of the ggpubr package to visualize the MA plot (MA-plot), the font.legend parameter and the font.main parameter to set the title and legend
分成两栏后文字顺序混乱的问题解决【写期刊论文时】
Excel quickly aligns the middle name of the table (two-word name and three-word name alignment)
Synchronized and volatile interview brief summary
看交互设计如何集成到Scrum敏捷流程中
R语言ggplot2可视化:使用ggpubr包的ggboxplot函数可视化分组箱图、使用ggpar函数改变图形化参数(legend、修改可视化图像的图例在整图中的位置)
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
Essential Learning for Getting Started with Unity Shader - Transparency Effect
修改SQL语言实现Mysql 多表关联查询优化
Doing things software development - the importance of law and understanding of reasonable conclusions
OpenCV测量物体的尺寸技能 get~
TRACE32 - C source code association
名创优品斥资6.95亿购买创始人叶国富所持办公楼股权
Selenium自动化中无头浏览器的应用
LeetCode二叉树系列——110.平衡二叉树
安装Xshell并使用其进行Ymodem协议的串口传输



![[CUDA study notes] First acquaintance with CUDA](/img/a2/f322ebe9dc483028f68882ee2c866b.png)





