Skip to content

python: attempts to fix 3d mat parsing problem for dnn#25810

Merged
asmorkalov merged 4 commits intoopencv:4.xfrom
fengyuentau:python/fix_parsing_3d_mat_in_dnn
Jul 4, 2024
Merged

python: attempts to fix 3d mat parsing problem for dnn#25810
asmorkalov merged 4 commits intoopencv:4.xfrom
fengyuentau:python/fix_parsing_3d_mat_in_dnn

Conversation

@fengyuentau
Copy link
Copy Markdown
Member

@fengyuentau fengyuentau commented Jun 24, 2024

Fixes #25762 #23242
Relates #25763 #19091

Although cv.Mat has already been introduced to workaround this problem, people do not know it and it kind of leads to confusion with numpy.array. This patch adds a "switch" to turn off the auto multichannel feature when the API is from cv::dnn::Net (more specifically, setInput) and the parameter is of type Mat. This patch only leads to changes of three places in pyopencv_generated_types_content.h:

static PyObject* pyopencv_cv_dnn_dnn_Net_setInput(PyObject* self, PyObject* py_args, PyObject* kw)
{
...
- pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 0)) &&
+ pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 8)) &&
...
}

// I guess we also need to change this as one-channel blob is expected for param
static PyObject* pyopencv_cv_dnn_dnn_Net_setParam(PyObject* self, PyObject* py_args, PyObject* kw)
{
...
- pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 0)) )
+ pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 8)) )
...
- pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 0)) )
+ pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 8)) )
...
}

Others are unchanged, e.g. dnn_SegmentationModel and stuff like that.

Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

  • I agree to contribute to the project under Apache 2 License.
  • To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
  • The PR is proposed to the proper branch
  • There is a reference to the original bug report and related work
  • There is accuracy test, performance test and test data in opencv_extra repository, if applicable
    Patch to opencv_extra has the same branch name.
  • The feature is well documented and sample code can be built with the project CMake

@asmorkalov
Copy link
Copy Markdown
Contributor

@fengyuentau should work for DNN as the most popular case, but what about other functions, e.g. contrib? There is no way to define the same behaviour there.

@fengyuentau
Copy link
Copy Markdown
Member Author

@fengyuentau should work for DNN as the most popular case, but what about other functions, e.g. contrib? There is no way to define the same behaviour there.

Could you give an example on functions in contrib? I think, if we extract the filter self.mat_single_channel = (namespace == "cv.dnn" and classname == "dnn_Net") and put it in any place we want, we can do the same for other functions as well.

@vpisarev
Copy link
Copy Markdown
Contributor

vpisarev commented Jun 28, 2024

@fengyuentau, thank you! I'd suggest to add another function/method parameter attribute CV_INP_ND to bindings generator (hdr_parser.py) so that Python bindings generator could call ndarray=>cv::Mat conversion with proper flags.

e.g.

class Net { ...
CV_WRAP void setInput(CV_INP_ND InputArray tensor);
};

@fengyuentau
Copy link
Copy Markdown
Member Author

@fengyuentau, thank you! I'd suggest to add another function/method parameter attribute CV_INP_ND to bindings generator (hdr_parser.py) so that Python bindings generator could call ndarray=>cv::Mat conversion with proper flags.

e.g.

class Net { ...
CV_WRAP void setInput(CV_INP_ND InputArray tensor);
};

Discussed and decided to use CV_ND for the macro.

@fengyuentau
Copy link
Copy Markdown
Member Author

Done refactor with CV_ND.

@fengyuentau fengyuentau added this to the 4.11.0 milestone Jun 28, 2024
@asmorkalov asmorkalov added pr: needs test New functionality requires minimal tests set and removed RFC pr: Discussion Required labels Jun 28, 2024
@asmorkalov
Copy link
Copy Markdown
Contributor

@fengyuentau Please add/modify python tests to cover the feature.

Copy link
Copy Markdown
Contributor

@opencv-alalek opencv-alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Output arrays should be handled too.

E.g. forward(OutputArrayOfArrays

@opencv-alalek
Copy link
Copy Markdown
Contributor

There is dedicated header which is used to test binding generator features: https://github.com/opencv/opencv/blob/4.x/modules/core/include/opencv2/core/bindings_utils.hpp

@fengyuentau
Copy link
Copy Markdown
Member Author

Output arrays should be handled too.

E.g. forward(OutputArrayOfArrays

Specifically speaking for numpy, there is no multi-channel numpy array. So there is no need to mark output.

@opencv-alalek
Copy link
Copy Markdown
Contributor

There is ability to pass pre-allocated arrays via such API. So shapes of these arrays should be properly passed to C++ code.

@fengyuentau

This comment was marked as outdated.

@asmorkalov asmorkalov removed the pr: needs test New functionality requires minimal tests set label Jul 1, 2024
Copy link
Copy Markdown
Contributor

@asmorkalov asmorkalov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@fengyuentau
Copy link
Copy Markdown
Member Author

fengyuentau commented Jul 1, 2024

There is ability to pass pre-allocated arrays via such API. So shapes of these arrays should be properly passed to C++ code.

@opencv-alalek I updated code according to your comment. This introduce a convention:

  • The pre-allocated is a np.array, we treat it as a Mat and parse with ND flag.
  • The pre-allocated is a tuple of np.arrayl, we treat it as a vector of Mat and the ND flag can still apply if any.

Before this commit, the first dimension of a pre-allocated np.array is treated as the length of vector and the inner arrays are parsed as the elements of the vector.

@asmorkalov
Copy link
Copy Markdown
Contributor

@opencv-alalek could you take a look again?

@asmorkalov asmorkalov merged commit 5510718 into opencv:4.x Jul 4, 2024
@fengyuentau fengyuentau deleted the python/fix_parsing_3d_mat_in_dnn branch July 4, 2024 05:34
vrabaud pushed a commit to vrabaud/opencv that referenced this pull request Jul 4, 2024
…d_mat_in_dnn

python: attempts to fix 3d mat parsing problem for dnn opencv#25810

Fixes opencv#25762 opencv#23242
Relates opencv#25763 opencv#19091

Although `cv.Mat` has already been introduced to workaround this problem, people do not know it and it kind of leads to confusion with `numpy.array`. This patch adds a "switch" to turn off the auto multichannel feature when the API is from cv::dnn::Net (more specifically, `setInput`) and the parameter is of type `Mat`. This patch only leads to changes of three places in `pyopencv_generated_types_content.h`:

```.diff
static PyObject* pyopencv_cv_dnn_dnn_Net_setInput(PyObject* self, PyObject* py_args, PyObject* kw)
{
...
- pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 0)) &&
+ pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 8)) &&
...
}

// I guess we also need to change this as one-channel blob is expected for param
static PyObject* pyopencv_cv_dnn_dnn_Net_setParam(PyObject* self, PyObject* py_args, PyObject* kw)
{
...
- pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 0)) )
+ pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 8)) )
...
- pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 0)) )
+ pyopencv_to_safe(pyobj_blob, blob, ArgInfo("blob", 8)) )
...
}
```

Others are unchanged, e.g. `dnn_SegmentationModel` and stuff like that.

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
@asmorkalov asmorkalov mentioned this pull request Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ONNX does not work for BMM function

5 participants