<jupyter_start><jupyter_text>RANSAC 2D vonal Ebben a leckében a RANSAC (RANdom SAmple Consensus) módszert mutatjuk be egy egyszerű példán.RANSAC egy robosztus módszer geometriai elemek megtalálására egy pontfelhőben. Egy vonal megtalálásához egy síkbeli ponthalmazon a következő lépéseket hajtjuk végre.1. válasszunk ki két pontot véletlenszerűen a ponthalmazból2. írjuk fel a két ponton átmenő egyenes egyenletét3. keressük meg a vonal közelébe eső pontokat (eg tolerancián belül)4. ha a közelben lévő pontok száma több mint az eddigi maximum akkor őrizzük meg mint az eddigi legjobb megoldás5. ismételjük az első lépéstől amíg elérjük el nem érjük a megadott ismétlési számotEz az algoritmus nem determinisztikus, azaz, ha többször futtatjuk eltérő eredményeket kaphatunk. Azonban, ha az ismétlési szám elég nagy, akkor közel azonos megoldásokat kapunk.Az algoritmus két konstans értéktől függ, az egyenestől való maximális távolságtól és az ismétlési számtól.<jupyter_code># Python packages used
import numpy as np                      # for array operations
from matplotlib import pyplot as plt    # for graphic output
from math import sqrt
# parameters
tolerance = 2.5           # max distance from the plane to accept point
rep = 1000                # number of repetition<jupyter_output><empty_output><jupyter_text>Az ismétlési szám elég magas. Véletlenszámokat használunk a 2D-s pontok generálásához. *n* pontot generálunk a (0.451 x - y + 2 = 0) egyens közelében. További *k* pontot generálunk "zajként".<jupyter_code>n = 100                     # number of inliers
k = 200                     # number of outliers
range = 100.0               # range of x, y coordinates
l = [0.451, -1.0, 2.0]      # line equation ax + by + c = 0
x = np.zeros(n+k)
y = np.zeros(n+k)
# points near to the line
x[:n] = np.random.rand(n) * range
y[:n] = -l[0] / l[1] * x[:n] - l[2] / l[1] + (np.random.rand(n) * 2 * tolerance - tolerance)
# outlier points (noise)
x[n:] = np.random.rand(k) * range
y[n:] = np.random.rand(k) * range
points = np.c_[x, y, np.full(n+k, 1.0)] # put together inliers and outliers<jupyter_output><empty_output><jupyter_text>Jelenítsük meg a generált pontokat és az egyenest.<jupyter_code>fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot()
ax.scatter(x, y)
ax.plot([0,100], [-l[2] / l[1], -l[0] / l[1] * 100 - l[2] / l[1]], 'r', label='original line')
_ = ax.set_title('Pointok és az egyenes')
best_n = 0          # number of points on the best fit line so far
best_i = 0          # iteration index of best fit line so far
best_inliers = np.array([]) # indices of inliers of the best fit line so far
for i in np.arange(rep):
    # select two random points
    p = []  # list of random indices for points
    while len(p) != 2:
        p = list(set(np.random.randint(n+k, size=2))) # remove repeated random integers
    p1 = points[p]  # randomly selected points
    x1 = p1[:,0]    # x coordinates
    y1 = p1[:,1]    # y coordinates
    # line equation from the two points using homogenouos coordinates
    l1 = np.array([y1[0] - y1[1], x1[1] - x1[0], x1[0] * y1[1] - x1[1] * y1[0]])
    l1 = l1 / sqrt(l1[0]**2 + l1[1]**2)     # normalize
    # select close points
    inliers = points[np.abs(np.dot(points, l1)) < tolerance]
    if inliers.shape[0] > best_n:
        # better solution found
        best_n = inliers.shape[0]
        best_i = i
        best_inliers = inliers.copy()
        best_line = l1.copy()
print(f'Legjobb megoldás {best_i} ismétlés után, pontok száma az egyenesen: {best_n}  egyenes: {best_line}')<jupyter_output>Legjobb megoldás 595 ismétlés után, pontok száma az egyenesen: 113  egyens: [ 0.41358096 -0.91046735  1.4446422 ]<jupyter_text>Futtasa többször a fenti kódblokkot és vegye észre az egyes egyenletének változását.Végül jelenítsük meg a legjobban illeszkedő egyenest.<jupyter_code>fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot()
ax.scatter(x, y)
ax.scatter(best_inliers[:,0], best_inliers[:,1], c='g')
ax.plot([0,100], [-l[2] / l[1], -l[0] / l[1] * 100 - l[2] / l[1]], 'g', label='eredeti vonal')
ax.plot([0,100], [-best_line[2] / best_line[1], -best_line[0] / best_line[1] * 100 - best_line[2] / best_line[1]], 'r', label='legjobb közelítés')
ax.legend()
_ = ax.set_title('RANSAC vonal')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11860845201961243, 'fraction_numerical': 0.037823955171608685, 'mean_word_length': 3.6565217391304348, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '102212', 'license': 'CC0-1.0', 'n_tokens_mistral': 1806, 'n_tokens_neox': 1735, 'n_words': 483, 'path': 'hungarian/ransac/ransac_vonal.ipynb', 'repo_name': 'beuholanda/tutorials', 'size': '4283'}