Tengo un gran conjunto de puntos aleatorios, , que, por razones desconocidas, parecen alinearse a lo largo de ciertas líneas:
Quiero calcular la pendiente de esas líneas (también sus otros parámetros, pero estoy preguntando sobre la pendiente aquí)
Separar las líneas algorítmicamente parece demasiado complejo. Supongo que necesitaría un algoritmo de clasificación, y esos nunca dan resultados estables.
Por eso solo estoy hablando de la pendiente.
Lo que hice:
Hice una muestra sintética generando líneas aleatorias:
el punto medio está dibujado en azul, y en este gráfico, las líneas tienen ° ángulo.
Tengo la intuición de que la suma de las distancias de todos los puntos a una línea que pasa por el punto azul debe ser máxima/mínima cuando la línea coincide con la pendiente que estoy buscando (o la pendiente perpendicular).
Calculé la distancia suma de todos los puntos a una línea que pasa por el centro, con ángulo , para diferentes ángulos (desde a ), y obtuve este gráfico:
Dibujé las líneas de puntos en °, y la distancia parece ser máxima alrededor del ángulo normal , por lo que sugiere que podría usar un solucionador de maximización para encontrar la pendiente normal a las líneas, maximizando la distancia de todos los puntos a una línea que pasa por el centro (punto azul).
Parece funcionar para diferentes ángulos que probé, pero no estoy seguro de si ese es el procedimiento correcto.
Además, la distancia no es mínima cuando la pendiente es paralela a las rectas.
EDITAR: acabo de notar que si los puntos se agrupan en dos grupos distantes, independientemente de la orientación de las líneas, la distancia máxima sería la que separa los grupos. ¿Quizás las transformadas de Fourier podrían detectar la orientación de las líneas?
Usando la transformación de Hough (ver aquí) sobre un mapa de bits extraído de la figura original y con algo de ayuda de un repositorio de python. El proceso comienza con la imagen proporcionada sbVut.png
import numpy as np
from skimage.transform import hough_line, hough_line_peaks
import matplotlib.pyplot as plt
from matplotlib import cm
from PIL import Image
"""
To transform the sbVut.png image into sbVut.bmp
"""
img = Image.open('/home/test/Desktop/sbVut.png')
(w,h) = img.size
for i in range(w):
for j in range(h):
(r,g,b) = img.getpixel((i,j))
r = 255-r
g = 255-g
b = 255-b
img.putpixel((i,j),(r,g,b))
thresh = 200
fn = lambda x : 255 if x > thresh else 0
r = img.convert('1')
r.save('/home/test/Desktop/sbVut.bmp')
"""
Begins the Hough transform
"""
image = np.array(Image.open('/home/test/Desktop/sbVut.bmp'))
# Classic straight-line Hough transform
(h, theta, d) = hough_line(image)
# Generating figure 1
(fig, axes) = plt.subplots(1, 3, figsize=(15, 6),
subplot_kw={'adjustable': 'box'})
ax = axes.ravel()
ax[0].imshow(image, cmap=cm.gray)
ax[0].set_title('Input image')
ax[0].set_axis_off()
ax[1].imshow(np.log(1 + h),
extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap=cm.gray, aspect=1/1.5)
ax[1].set_title('Hough transform')
ax[1].set_xlabel('Angles (degrees)')
ax[1].set_ylabel('Distance (pixels)')
ax[1].axis('image')
ax[2].imshow(image, cmap=cm.gray)
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle)
ax[2].plot((0, image.shape[1]), (y0, y1), '-r')
ax[2].set_xlim((0, image.shape[1]))
ax[2].set_ylim((image.shape[0], 0))
ax[2].set_axis_off()
ax[2].set_title('Detected lines')
plt.tight_layout()
plt.show()
y los resultados
Como los puntos son densos, los segmentos serán aislados por un algoritmo de componentes conectados (o contorneado en OpenCV). No hay ningún cuidado especial que tomar.
Para cada blob, puede encajar una línea, pero supongo que solo con unir los puntos extremos es suficiente.
A continuación, los ángulos formados con la vertical (usando el rectángulo de área mínima) para las 50 manchas más grandes.
El método empleado por nosotros:
Alfa = 38 +/- 2 gradosImagen producida:
Nota.
Un método más robusto puede ser considerar en su lugar los ángulos de los ejes menores de las elipses de inercia
con el eje x.
El software complementario gratuito solo de origen (Delphi Pascal) está disponible en el sitio: publicaciones/referencias de MSE 2021
Descargo de responsabilidad . Todo lo gratis viene sin garantía :-(y sin árbitro)
Glärbo
Raxi Ral
greg martin
Glärbo
Glärbo
motivos
Stephen Montgomery Smith
usuario65203