Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

goodFeaturesToTrack implementation does not correspond with Python implementation #1736

Closed
rene-wilbers-adesso opened this issue Jan 14, 2025 · 0 comments · Fixed by #1738
Closed

Comments

@rene-wilbers-adesso
Copy link
Contributor

rene-wilbers-adesso commented Jan 14, 2025

Summary of your issue

When I run keypoint detection with Cv2.goodFeaturesToTrack I get good results but they do not correspond with the results I get from the same version of openCV in python and exactly the same inputs.

Environment

MacOS 15.1.1
dotnet 8.0
python 3.9.6

OpenCV versions:
python (pypi): opencv-python-headless 4.10.0.84

OpenCVsharp: pulled main branch of this repo and made my own build with cmake (.dylib)

Also included this in my . csproj: <PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />

What did you do when you faced the problem?

Confirmed the issue by double checking whether input matrix and other parameters are exactly equal: they are.

Example code:

using OpenCvSharp;
using System;

class Program
{
    static void DetectAndPlotKeypoints(string imagePath)
    {
        // print opencv version
        Console.WriteLine($"OpenCV version: {Cv2.GetVersionString()}");

        // Read the image
        using var img = Cv2.ImRead(imagePath);
        // Crop the image to match Python implementation
        var rect = new Rect(310, 494, 432 - 310, 642 - 494);
        var croppedImg = img[rect];
        using var gray = croppedImg.CvtColor(ColorConversionCodes.BGR2GRAY);


        // Get image dimensions and pixel sum
        int height = gray.Height;
        int width = gray.Width;
        int pixelSum = (int)gray.Sum().Val0;
        Console.WriteLine($"Image height: {height}");
        Console.WriteLine($"Image width: {width}");
        Console.WriteLine($"Sum of pixel values: {pixelSum}");

        // Detect keypoints using GoodFeaturesToTrack
        Point2f[] corners = Cv2.GoodFeaturesToTrack(
            gray,
            maxCorners: 100,
            qualityLevel: 0.0001,
            minDistance: 10,
            mask: null!,
            blockSize: 3,
            useHarrisDetector: false,
            k: 0.04
        );

        // Draw keypoints
        using var imgWithKeypoints = croppedImg.Clone();
        foreach (var corner in corners)
        {
            imgWithKeypoints.Circle(
                center: new Point((int)corner.X, (int)corner.Y),
                radius: 3,
                color: new Scalar(0, 255, 0),
                thickness: -1
            );
        }

        // Save results instead of displaying
        imgWithKeypoints.ImWrite("result_opencvsharp.png");
        Console.WriteLine($"Number of keypoints detected: {corners.Length}");
    }

    static void Main(string[] args)
    {
        string imagePath = "frame1.png"; // Replace with your image path
        DetectAndPlotKeypoints(imagePath);
    }
}
import cv2
import numpy as np
import matplotlib.pyplot as plt

print(f"OpenCV version: {cv2.__version__}")

def detect_and_plot_keypoints(image_path):
    # Read the image
    img = cv2.imread(image_path)
    img = img[494:642, 310:432]
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # Get image dimensions and pixel sum
    height, width = gray.shape
    pixel_sum = np.sum(gray)
    print(f"Image height: {height}")
    print(f"Image width: {width}")
    print(f"Sum of pixel values: {pixel_sum}")
    
    # Detect keypoints using GoodFeaturesToTrack
    
    corners = cv2.goodFeaturesToTrack(
        gray,
        maxCorners=100,  # Maximum number of corners to detect
        qualityLevel=0.01,  # Minimum quality level
        minDistance=10,  # Minimum Euclidean distance between corners
        blockSize=3  # Size of neighborhood considered
    )
    corners = np.int32(corners)
    
    # Draw keypoints
    img_with_keypoints = img.copy()
    for corner in corners:
        x, y = corner.ravel()
        cv2.circle(img_with_keypoints, (x, y), 3, (0, 255, 0), -1)
    
    # Display results
    plt.figure(frameon=False)
    plt.imshow(cv2.cvtColor(img_with_keypoints, cv2.COLOR_BGR2RGB))
    plt.axis('off')
    plt.savefig('result_python.png', bbox_inches='tight', pad_inches=0)
    
    return len(corners)

if __name__ == "__main__":
    image_path = "frame1.png"  # Replace with your image path
    num_keypoints = detect_and_plot_keypoints(image_path)
    print(f"Number of keypoints detected: {num_keypoints}") 

Output:

dotnet:

OpenCV version: 4.10.0
Image height: 148
Image width: 122
Sum of pixel values: 1195826
Number of keypoints detected: 34

python:

OpenCV version: 4.10.0
Image height: 148
Image width: 122
Sum of pixel values: 1195826
Number of keypoints detected: 67

What did you intend to be?

Keypoints should have been equal. Both the number of keypoints and the coordinates are different.
The quality of the keypoints seem fine in both implementation, but the difference is a problem for me because we run modeling and evaluations in python but bring it into production in c#.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant