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

[jsk_perception/apply_mask] Avoid error in cvtColor when masked_image is empty #2725

Merged
merged 3 commits into from Sep 22, 2022

Conversation

iory
Copy link
Member

@iory iory commented Sep 9, 2022

What is this?

From opencv version 4, cvtColor doesn't support empty matrix.
If ~clip is true, the output mask size could be (w, h) = (0, 0) size.
In that case, the program dies in the cvtColor function for bgra and rgba image.
This PR fixes the bug.

In [1]: import cv2
   ...: import numpy as np
   ...: print('cv2.__version__: {}'.format(cv2.__version__))
   ...: cv2.cvtColor(np.empty((0, 0, 3), dtype=np.uint8), cv2.COLOR_BGR2RGB)
   ...:
cv2.__version__: 2.4.8
In [1]: import cv2
   ...: import numpy as np
   ...: print('cv2.__version__: {}'.format(cv2.__version__))
   ...: cv2.cvtColor(np.empty((0, 0, 3), dtype=np.uint8), cv2.COLOR_BGR2RGB)
   ...:
cv2.__version__: 3.2.0
In [1]: import cv2
   ...: import numpy as np
   ...: print('cv2.__version__: {}'.format(cv2.__version__))
   ...: cv2.cvtColor(np.empty((0, 0, 3), dtype=np.uint8), cv2.COLOR_BGR2RGB)
   ...:
cv2.__version__: 4.5.1

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
Input In [1], in <cell line: 4>()
      2 import numpy as np
      3 print('cv2.__version__: {}'.format(cv2.__version__))
----> 4 cv2.cvtColor(np.empty((0, 0, 3), dtype=np.uint8), cv2.COLOR_BGR2RGB)

error: OpenCV(4.5.1) /tmp/pip-req-build-jr1ur_cf/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

@iory
Copy link
Member Author

iory commented Sep 15, 2022

We can reproduce the error with the following launch file.

<launch>

  <arg name="gui" default="true" />
  <arg name="launch_manager" default="true" />

  <arg name="MANAGER" default="sample_manager" />
  <node name="$(arg MANAGER)"
        pkg="nodelet" type="nodelet" args="manager"
        if="$(arg launch_manager)"
        output="screen" />

  <node name="image_publisher"
        pkg="jsk_perception" type="image_publisher.py">
    <rosparam subst_value="true">
      file_name: $(find jsk_perception)/sample/image/sample_alpha.png
      encoding: bgra8
      publish_info: false
    </rosparam>
  </node>
  <arg name="INPUT_IMAGE" default="image_publisher/output" />

  <node name="mask_publisher"
        pkg="jsk_perception" type="mask_image_generator">
    <remap from="~input" to="$(arg INPUT_IMAGE)" />
    <rosparam>
      offset_x: 256
      offset_y: 256
      width: 256
      height: 256
    </rosparam>
  </node>
  <arg name="MASK_IMAGE" default="mask_publisher/output" />

  <node name="apply_mask_image"
        pkg="nodelet" type="nodelet"
        args="load jsk_perception/ApplyMaskImage $(arg MANAGER)"
        respawn="true" >
    <remap from="~input" to="$(arg INPUT_IMAGE)" />
    <remap from="~input/mask" to="$(arg MASK_IMAGE)" />
    <rosparam>
      approximate_sync: true
    </rosparam>
  </node>

  <group if="$(arg gui)">
    <node name="image_view0"
          pkg="image_view" type="image_view">
      <remap from="image" to="$(arg INPUT_IMAGE)" />
    </node>
    <node name="image_view1"
          pkg="image_view" type="image_view">
      <remap from="image" to="$(arg MASK_IMAGE)" />
    </node>
    <node name="image_view2"
          pkg="image_view" type="image_view">
      <remap from="image" to="apply_mask_image/output" />
    </node>
  </group>

</launch>

Copy link
Member

@nakane11 nakane11 left a comment

Choose a reason for hiding this comment

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

When an input mask image does not have non-zero values, as of the launch file above, the size of clipped mask (max region) is (0, 0).
If (0, 0) image is passed to cvtColor, the error could occur.
I confirmed that this problem is caused in noetic and not in melodic. This change never affects current behaviours.

Copy link
Member

@nakane11 nakane11 left a comment

Choose a reason for hiding this comment

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

Please consider the case where mask_black_to_transparent is true.

… is empty in case of mask_black_to_transparent is True
@iory
Copy link
Member Author

iory commented Sep 20, 2022

@nakane11 Thanks! I fixed the case.

Copy link
Member

@nakane11 nakane11 left a comment

Choose a reason for hiding this comment

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

Thank you too!
I confirmed that the error can also be avoided in the case of mask_black_to_transparent=true.

@k-okada k-okada merged commit 1afa5ff into jsk-ros-pkg:master Sep 22, 2022
@iory iory deleted the apply-mask-fix-cvtColor branch September 22, 2022 01:55
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.

None yet

3 participants