[Python] Why don't I get the expected neighbor indices with OpenCVs KNearestNeighbour?

Discussão em 'Python' iniciado por Stack, Abril 28, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to use OpenCVs KNearestNeighbours in python. I'd like to use it to extract Euclidean distances to the nearest neighbour. The outputs are not what I expect, which I think means I'm either incorrect about what the function is supposed to return OR I'm inputting incorrect arguments.

    Specifically I'd like to know how to correctly get the neighbour indices

    Here's an example where I compute distances both manually and with OpenCV. Distances match but indices do not.

    Update


    I originally asked about distances as well but now realize that opencv returns squared distances. Code and output are adjusted accordingly.

    Code


    import numpy as np
    import cv2


    np.random.seed(42)

    # Example training data with two features
    X_train = np.random.rand(25, 2).astype(np.float32) # 25 samples, 2 features
    y_train = np.random.randint(0, 2, (25, 1)).astype(np.float32) # 25 labels (binary classification)

    # Example test data with two features
    X_test = np.random.rand(5, 2).astype(np.float32) # 5 test samples, 2 features

    # Create and train the k-NN model
    knn = cv2.ml.KNearest_create()
    knn.train(X_train, cv2.ml.ROW_SAMPLE, y_train)

    # Perform k-NN classification
    ret, results, neighbors, distances = knn.findNearest(X_test, k=1)

    # Manually calculate Euclidean distances
    for i, test_sample in enumerate(X_test):
    # Calculate Euclidean distances to all training samples
    manual_distances = np.sum((X_train - test_sample) ** 2, axis=1)

    # Find the nearest neighbor manually
    nearest_index = np.argmin(manual_distances)
    nearest_distance = manual_distances[nearest_index]

    # Compare with OpenCV's output
    print(f"Test sample {i}:")
    print(f" Manual nearest distance: {nearest_distance}")
    print(f" OpenCV nearest distance: {distances[0]}")
    print(f" Manual nearest neighbor index: {nearest_index}")
    print(f" OpenCV nearest neighbor index: {neighbors[0]}")

    Output


    Test sample 0:
    Manual nearest distance: 0.0452449657022953
    OpenCV nearest distance: 0.0452449657022953
    Manual nearest neighbor index: 0
    OpenCV nearest neighbor index: 0.0

    Test sample 1:
    Manual nearest distance: 0.011125250719487667
    OpenCV nearest distance: 0.011125250719487667
    Manual nearest neighbor index: 15
    OpenCV nearest neighbor index: 1.0

    Test sample 2:
    Manual nearest distance: 0.004638621583580971
    OpenCV nearest distance: 0.004638621583580971
    Manual nearest neighbor index: 18
    OpenCV nearest neighbor index: 1.0

    Test sample 3:
    Manual nearest distance: 0.016473062336444855
    OpenCV nearest distance: 0.016473062336444855
    Manual nearest neighbor index: 20
    OpenCV nearest neighbor index: 1.0

    Test sample 4:
    Manual nearest distance: 0.0013788070064038038
    OpenCV nearest distance: 0.0013788070064038038
    Manual nearest neighbor index: 9
    OpenCV nearest neighbor index: 0.0

    Continue reading...

Compartilhe esta Página