Skip to content
Snippets Groups Projects
Commit 326dae4a authored by Yuriy Maksymets's avatar Yuriy Maksymets
Browse files

Simple Hough transform line detection

parent 470b26dc
No related branches found
No related tags found
1 merge request!65Simple shape recognition
Pipeline #104665 failed
......@@ -13,25 +13,22 @@ describe("shape recognition", () => {
test("should recognize a simple horizontal line", () => {
const points = [[0, 0], [100, 0]]
const result = recognizeFromPoints(points)
expect(result).toBe(Shapes.line)
expect(result.shape).toBe(Shapes.line)
})
test("should recognize a simple vertical line", () => {
const points = [[0, 50], [0, -100]]
const result = recognizeFromPoints(points)
expect(result).toBe(Shapes.line)
expect(result.shape).toBe(Shapes.line)
})
test("should recognize a slightly curve horizontal line", () => {
const points = [[0, 0], [30, 10], [100, 2]]
const points = [[0, 0], [30, 5], [100, 2]]
const result = recognizeFromPoints(points)
expect(result).toBe(Shapes.line)
expect(result.shape).toBe(Shapes.line)
})
test("should not recognize a really curved horizontal line", () => {
const points = [[0, 0], [30, 30], [100, -4]]
const result = recognizeFromPoints(points)
expect(result).not.toBe(Shapes.line)
expect(result.shape).not.toBe(Shapes.line)
})
})
......
function dtor(a) {
return (Math.PI * a) / 180
}
function cos(a) {
return Math.cos(dtor(a))
}
function sin(a) {
return Math.sin(dtor(a))
}
const rhoStep = 5
const angleStep = 90
const numAngleCells = 180 / angleStep
const rhoMax = 1000
function findMaxInHough(accum, threshold) {
let max = 0
// let bestRho = 0
let bestTheta = 0
for (let i = 0; i < numAngleCells; i++) {
for (let j = 0; j < accum[i].length; j++) {
if (accum[i][j] > max) {
max = accum[i][j]
// bestRho = j
bestTheta = i
}
}
}
// bestRho <<= 1
// bestRho -= rhoMax
// bestRho *= rhoStep
bestTheta *= angleStep
if (max > threshold) {
if (bestTheta === 90) {
return 90
} else {
return 0
}
}
return undefined
}
function constructHoughAccumulator(accumulator, x, y) {
for (let thetaIndex = 0; thetaIndex < numAngleCells; thetaIndex++) {
const theta = thetaIndex * angleStep
let rho = x * cos(theta) + y * sin(theta)
rho = Math.floor(rho)
rho += rhoMax
rho >>= 1
rho /= rhoStep
rho = Math.floor(rho)
if (accumulator[thetaIndex] == undefined) accumulator[thetaIndex] = []
if (accumulator[thetaIndex][rho] == undefined) {
accumulator[thetaIndex][rho] = 1
} else {
accumulator[thetaIndex][rho]++
}
}
}
function recognizeFromPoints(points) {
return {
shape: Shapes.rectangle,
points,
const accum = Array(numAngleCells)
points.forEach((x) => constructHoughAccumulator(accum, ...x))
const angle = findMaxInHough(accum, points.length - 1)
if (angle !== undefined) {
return {
shape: Shapes.line,
points,
}
}
return {}
}
export const Shapes = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment