Skip to content

G-API: Wrap render functionality to python#20284

Merged
alalek merged 9 commits intoopencv:masterfrom
TolyaTalamanov:at/wrap-render
Jul 1, 2021
Merged

G-API: Wrap render functionality to python#20284
alalek merged 9 commits intoopencv:masterfrom
TolyaTalamanov:at/wrap-render

Conversation

@TolyaTalamanov
Copy link
Copy Markdown
Contributor

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 other license that is incompatible with OpenCV
  • The PR is proposed to proper branch
  • There is reference to 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

Build configuration

force_builders=Custom,Custom Win,Custom Mac
build_gapi_standalone:Linux x64=ade-0.1.1f
build_gapi_standalone:Win64=ade-0.1.1f
build_gapi_standalone:Mac=ade-0.1.1f
build_gapi_standalone:Linux x64 Debug=ade-0.1.1f

Xbuild_image:Custom=centos:7
Xbuildworker:Custom=linux-1
build_gapi_standalone:Custom=ade-0.1.1f

build_image:Custom=ubuntu-openvino-2021.3.0:20.04
build_image:Custom Win=openvino-2021.2.0
build_image:Custom Mac=openvino-2021.2.0

test_modules:Custom=gapi,python2,python3,java
test_modules:Custom Win=gapi,python2,python3,java
test_modules:Custom Mac=gapi,python2,python3,java

buildworker:Custom=linux-1
# disabled due high memory usage: test_opencl:Custom=ON
test_opencl:Custom=OFF
test_bigdata:Custom=1
test_filter:Custom=*

@TolyaTalamanov TolyaTalamanov changed the title [G-API] Wrap render functionality to python G-API: Wrap render functionality to python Jun 21, 2021


# FIXME: On the c++ side every class is placed in cv2 module.
cv.gapi.wip.draw.Rect = cv.gapi_wip_draw_Rect
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@alalek How ugly is it ? Is there another option ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure why you need that. There are many other classes from nested namespaces which are located properly.

AFAIK, there is some bug with Python ctors (this is why "create" method is used).
It is better to fix that problem instead of replacing classes with functions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not sure why you need that. There are many other classes from nested namespaces which are located properly.
Could you provide any examples ? Looks like all classes is placed in cv2 module.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks like it is not supported properly for now.

BTW, cv.gapi_wip_draw_Rect is a function, not a type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

From generated file:

CVPY_TYPE(gapi_wip_draw_Rect, gapi_wip_draw_Rect, cv::gapi::wip::draw::Rect, Rect, NoBase, pyopencv_cv_gapi_wip_draw_gapi_wip_draw_Rect_Rect)

template <>
PyObject* pyopencv_from(const cv::gapi::wip::draw::Prim& prim)
{
switch (prim.index()) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I believe it's possible to implement pyopencv_from for generic variant by using visitor, but it's not merged yet.

bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prim& value, const ArgInfo& info)
{
#define TRY_EXTRACT(Prim) \
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_gapi_wip_draw_##Prim##_TypePtr))) \
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@alalek Is there any way to implemente it via more high level functions ? pyopencv_to/pyopencv_to_safe aren't suitable there, are they ? Because they set an error in case mismatch.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure that do you mean here.
"dynamic types" are handled though switches/virtual functions.

If you don't want to follow pyopencv_to/pyopencv_from conventions, then please change names of these functions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What do u mean by "dynamic types". Is the cv::variant<Types...> is a dynamic type ?
It seems to me since cv::variant<> has the limited number of possible types it can be wrapped like this:

cv::gapi::wip::draw::Rect rect;
if (pyopencv_to(obj, rect, info))
{
    value = rect;
    return true;
}
...
if(pyopencv_to(obj, text, info)
{
    value = text;
    return false;
}

// set error
return false;

But it doesn't work because in case fail first pyopencv_to setup an error.

Is it possible to implement pyopencv_to for variant<> following all conventions somehow else it's done above ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Variant implementation always has a tag/kind field which says which underlying object is stored.
There is NO sequence of calls.
There is switch(tag) with ONE call.

So you need to determine what is the "tag" value in that case. Perhaps switching over PyObject_TypeCheck is enough.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

But in this case variant<> is empty, isn't it ?
It seems I can't just go through switch to determinate the type, cuz there is no stored object so far

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've implemented pyopencv_from like you proposed above



# FIXME: On the c++ side every class is placed in cv2 module.
cv.gapi.wip.draw.Rect = cv.gapi_wip_draw_Rect
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure why you need that. There are many other classes from nested namespaces which are located properly.

AFAIK, there is some bug with Python ctors (this is why "create" method is used).
It is better to fix that problem instead of replacing classes with functions.

bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prim& value, const ArgInfo& info)
{
#define TRY_EXTRACT(Prim) \
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_gapi_wip_draw_##Prim##_TypePtr))) \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure that do you mean here.
"dynamic types" are handled though switches/virtual functions.

If you don't want to follow pyopencv_to/pyopencv_from conventions, then please change names of these functions.

TRY_EXTRACT(Image)
TRY_EXTRACT(Poly)

return false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Python error should be raised with proper message.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

@TolyaTalamanov
Copy link
Copy Markdown
Contributor Author

@alalek @mpashchenkov Could you have a look, please ?

@TolyaTalamanov
Copy link
Copy Markdown
Contributor Author

@alalek I answered the comments, could check it one more time, please ?

@TolyaTalamanov
Copy link
Copy Markdown
Contributor Author

@alalek CI is green, could you check it one more time, please ?

Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

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

Looks good to me

int lt_ = 8,
bool bottom_left_origin_ = false) :
GAPI_WRAP Text(const std::string& text_,
const cv::Point& org_,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It makes sense to put modifiers on a separate line:

GAPI_WRAP
Text(const std::string& text_,

(to avoid touching indentation on changes)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines +71 to +76
GAPI_WRAP Text() = default;

/*@{*/
std::string text; //!< The text string to be drawn
cv::Point org; //!< The bottom-left corner of the text string in the image
int ff; //!< The font type, see #HersheyFonts
double fs; //!< The font scale factor that is multiplied by the font-specific base size
cv::Scalar color; //!< The text color
int thick; //!< The thickness of the lines used to draw a text
int lt; //!< The line type. See #LineTypes
bool bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
GAPI_PROP std::string text; //!< The text string to be drawn
GAPI_PROP cv::Point org; //!< The bottom-left corner of the text string in the image
GAPI_PROP int ff; //!< The font type, see #HersheyFonts
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If you wrap default ctor, then it makes sense to use RW properties (like CV_PROP_RW) to allow updating of them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done



# FIXME: On the c++ side every class is placed in cv2 module.
cv.gapi.wip.draw.Rect = cv.gapi_wip_draw_Rect
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks like it is not supported properly for now.

BTW, cv.gapi_wip_draw_Rect is a function, not a type.

@alalek
Copy link
Copy Markdown
Member

alalek commented Jun 30, 2021

please rebase PR on new master code

@TolyaTalamanov
Copy link
Copy Markdown
Contributor Author

@alalek Rebased, CI is green

Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

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

Looks good to me 👍

int thick_ = 1,
int lt_ = 8,
int shift_ = 0) :
const cv::Scalar& color_,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Indent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@TolyaTalamanov
Copy link
Copy Markdown
Contributor Author

@alalek Could you merge it, please ?

@alalek alalek merged commit 9fe4949 into opencv:master Jul 1, 2021
@alalek alalek mentioned this pull request Oct 15, 2021
a-sajjad72 pushed a commit to a-sajjad72/opencv that referenced this pull request Mar 30, 2023
G-API: Wrap render functionality to python

* Wrap render Rect prim

* Add all primitives and tests

* Cover mosaic and image

* Handle error in pyopencv_to(Prim)

* Move Mosaic and Rect ctors wrappers to shadow file

* Use GAPI_PROP_RW

* Fix indent
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.

3 participants