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

Unexpect error when invoke cv2.sampsonDistance #25370

Open
4 tasks done
beanduan22 opened this issue Apr 8, 2024 · 10 comments
Open
4 tasks done

Unexpect error when invoke cv2.sampsonDistance #25370

beanduan22 opened this issue Apr 8, 2024 · 10 comments
Labels

Comments

@beanduan22
Copy link

System Information

Python version: 3.8.18
OpenCV python version: 4.9.0
Operating System / Platform: Windows-10-10.0.19045-SP0

Detailed description

cv2.error: OpenCV(4.9.0) D:\a\opencv-python\opencv-python\opencv\modules\calib3d\src\fundam.cpp:1214: error: (-215:Assertion failed) _pt1.type() == CV_64F && _pt2.type() == CV_64F && _F.type() == CV_64F in function 'cv::sampsonDistance'

all of the input param I set were float64

Steps to reproduce

import numpy as np
import cv2
pt1 = (np.random.rand(100, 1, 2)* 256).astype(np.float64)

pt2 = (np.random.rand(100, 1, 2)* 256).astype(np.float64)

m3 = (np.random.rand(3,3) * 256).astype(np.float64)

output = cv2.sampsonDistance(pt1, pt2, m3)
print(output)

Issue submission checklist

  • I report the issue, it's not a question
  • I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
  • I updated to the latest OpenCV version and the issue is still there
  • There is reproducer code and related data files (videos, images, onnx, etc)
@beanduan22 beanduan22 added the bug label Apr 8, 2024
@amitsingh19975
Copy link

I did some poking around and found the lines that are producing this bug.

bool ismultichannel = ndims == 3 && _sizes[2] <= CV_CN_MAX;

This line makes arguments first and second multichannel

type |= CV_MAKETYPE(0, channels);

This line changes the type from float64( type id 6) to some other invalid type with type id 14 ( = 6 bitwise or 8 )

I hope this helps in fixing the bug.

@amitsingh19975
Copy link

Possible fix if applicable

CV_Assert((_pt1.type() & CV_MAT_DEPTH_MASK) == CV_64F && (_pt2.type() & CV_MAT_DEPTH_MASK) == CV_64F && _F.type() == CV_64F);

@shekhar-chauhan
Copy link

I'd be more than happy to take over the issue if someone can do a basic code walkthrough for me, regarding what all places do I need to look into and such.

@Dhanwanth1803
Copy link
Contributor

Hey @beanduan22 . I started to read the documentation of the function cv2.sampsonDistance( ). The parameters state that the pt1 and pt2 should be two dimensional. I am not completely sure abt this but please let me know if its anything relevant. Hence I made those matrices 2D and they seem to work.
issue

@amitsingh19975
Copy link

Hey @beanduan22 . I started to read the documentation of the function cv2.sampsonDistance( ). The parameters state that the pt1 and pt2 should be two dimensional. I am not completely sure abt this but please let me know if its anything relevant. Hence I made those matrices 2D and they seem to work. issue

that's what I can tell by reading the code. If the extent exceeds 2, it'll encode it as a multi-channel array.

We could add another assert to check if it's a multi-channel array so that users can don't confuse this with an error.

@Dhanwanth1803
Copy link
Contributor

Hey @beanduan22 . I started to read the documentation of the function cv2.sampsonDistance( ). The parameters state that the pt1 and pt2 should be two dimensional. I am not completely sure abt this but please let me know if its anything relevant. Hence I made those matrices 2D and they seem to work. issue

that's what I can tell by reading the code. If the extent exceeds 2, it'll encode it as a multi-channel array.

We could add another assert to check if it's a multi-channel array so that users can don't confuse this with an error.

Any idea how we can do that? Do we need to do it manually?

@amitsingh19975
Copy link

amitsingh19975 commented Apr 10, 2024

You could use the bit mask since (CV_MAT_DEPTH_MASK) the normal type range is between 1 to 7 if I remember correctly. Just check if the type is valid double precision and if it is out of range.

Steps:

  • check if valid f64 (type & CV_MAT_DEPTH_MASK) == CV_F64
  • if the prior condition is true, check if the type > (CV_MAT_DEPTH_MASK - 1) <-- this tells if it's a multi-channel array.

It should cover that case for multi-channel; however, this is a check that is too far in the code. If we can pass argument constraints info to the pyopencv_to when you register the function for Python that would allow other functions to use it.

@amitsingh19975
Copy link

amitsingh19975 commented Apr 10, 2024

if the prior condition is true, check if the type > (CV_MAT_DEPTH_MASK - 1) <-- this tells if it's a multi-channel array. As you mentioned, we need to check for the conditions and manually handle the cases right?

Yes, you need manual handling of this case, but you could just assert with a message.

assert((_p1.type() < CV_MAT_DEPTH_MASK) && "Matrices or arrays of second order are only allowed") // This should indicate the user he's doing something wrong

Also I didn't understand the last part where you said we can pass argument to pyopencv_to. Can you please explain it again.

This is an idea that could be refined further or a better approach might be possible than this. I'm just trying to give you a possible fix.

template<>
bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info) {
    ...
    if (ndims != info.dims)  { // Or (info.min_dims <= ndims && ndims < info.max_dims)
      // handle error
    } 
}

Something along this line.

@Dhanwanth1803
Copy link
Contributor

if the prior condition is true, check if the type > (CV_MAT_DEPTH_MASK - 1) <-- this tells if it's a multi-channel array. As you mentioned, we need to check for the conditions and manually handle the cases right?

Yes, you need manual handling of this case, but you could just assert with a message.

assert((_p1.type() < CV_MAT_DEPTH_MASK) && "Matrices or arrays of second order are only allowed") // This should indicate the user he's doing something wrong

Also I didn't understand the last part where you said we can pass argument to pyopencv_to. Can you please explain it again.

This is an idea that could be refined further or a better approach might be possible than this. I'm just trying to give you a possible fix.

template<>
bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info) {
    ...
    if (ndims != info.dims)  { // Or (info.min_dims <= ndims && ndims < info.max_dims)
      // handle error
    } 
}

Something along this line.

Thank you soo much @amitsingh19975 . Let me try this

@amitsingh19975
Copy link

if the prior condition is true, check if the type > (CV_MAT_DEPTH_MASK - 1) <-- this tells if it's a multi-channel array. As you mentioned, we need to check for the conditions and manually handle the cases right?

Yes, you need manual handling of this case, but you could just assert with a message.

assert((_p1.type() < CV_MAT_DEPTH_MASK) && "Matrices or arrays of second order are only allowed") // This should indicate the user he's doing something wrong

Also I didn't understand the last part where you said we can pass argument to pyopencv_to. Can you please explain it again.

This is an idea that could be refined further or a better approach might be possible than this. I'm just trying to give you a possible fix.

template<>
bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info) {
    ...
    if (ndims != info.dims)  { // Or (info.min_dims <= ndims && ndims < info.max_dims)
      // handle error
    } 
}

Something along this line.

Thank you soo much @amitsingh19975 . Let me try this

BTW, these "dims", "min_dims", or "max_dims" members do not exist inside the ArgInfo class. They need to be added and initialized to the class. If you know this, ignore this comment.

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

No branches or pull requests

4 participants