当前位置:网站首页>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
边栏推荐
- 7. Summary of common interview questions
- 01 Encounter typescript, build environment
- 学习笔记12--路径-速度分解法之局部路径搜索
- Efficient use of RecyclerView Section 1
- Deployment application life cycle and Pod health check
- Excel quickly aligns the middle name of the table (two-word name and three-word name alignment)
- 工程水文学复习资料
- Matlab矩阵基本操作(定义,运算)
- WeChat chat record search in a red envelope
- 深入浅出边缘云 | 4. 生命周期管理
猜你喜欢

基于最小二乘法和SVM从天气预报中预测太阳能发电量(Matlab代码实现)

Jmeter常用的十大组件

Synchronized和volatile 面试简单汇总

分成两栏后文字顺序混乱的问题解决【写期刊论文时】

Ubantu专题5:设置静态ip地址
![[MySQL] Mysql paradigm and the role of foreign keys](/img/9d/a4295de26683d7bca2b8e9d14f754b.png)
[MySQL] Mysql paradigm and the role of foreign keys

mongo进入报错

TRACE32 - C source code association

Essential Learning for Getting Started with Unity Shader - Transparency Effect

Ubantu专题4:xshell、xftp连接接虚拟机以及设置xshell复制粘贴快捷键
随机推荐
org.apache.jasperException(could not initialize class org)
Internet banking stolen?This article tells you how to use online banking safely
LeetCode二叉树系列——110.平衡二叉树
Why is the field of hacking almost filled with boys?
Excel快速对齐表格的中姓名(两个字姓名和三个字姓名对齐)
Word表格转到Excel中
TRACE32——常用操作
7. Summary of common interview questions
Getting Started with TextBlock Control Basic Tools Usage, Get Started
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
Ubuntu Topic 5: Setting a Static IP Address
STM32(十)------- SPI通信
SQL、HQL、JPQL 到底有什么区别
微信聊天记录中搜索红包
what exactly is json (c# json)
学习笔记12--路径-速度分解法之局部路径搜索
QGIS 加载WMS数据,重新投影
Synchronized和volatile 面试简单汇总
thread_local 变量的析构顺序
Getting started with UnityShader (3) - Unity's Shader