-
Notifications
You must be signed in to change notification settings - Fork 74k
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
Add colors
support for tf.image.draw_bounding_boxes
#24282
Add colors
support for tf.image.draw_bounding_boxes
#24282
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. Any reason why we should make colors an input argument vs an attribute? Is it useful to send the colors as a list of tensors? Advantage of using an attribute is we won't need to add a new V2 op. Using an attribute might also help avoid the copying of the color vector in draw_bounding_box_op.cc.
@asimshankar @jaingaurav I take a look at the |
Attribute values can be tensors as well (though the only real example of that is the Now, whether this should be an attribute or an input pretty much depends on whether the list of colors is something that is computed in the graph or is static. The former is certainly more general. Shouldn't this PR also set things up so that |
(From API review): Using an input seems appropriate for this. So, please go ahead and update |
@asimshankar Thanks for the review. The PR has been updated with v1 pointing to old behavior and v2 allows colors input. Let me know if this is the expected implementation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for the late reply, some suggestions.
{1, 1, 0, 1}, {0, 0, 1, 1}, {1, 0, 0, 1}, {0, 1, 0, 1}, | ||
{0.5, 0, 0.5, 1}, {0.5, 0.5, 0, 1}, {0.5, 0, 0, 1}, {0, 0, 0.5, 1}, | ||
{0, 1, 1, 1}, {1, 0, 1, 1}, | ||
}; | ||
|
||
std::vector<std::vector<float>> color_table; | ||
for (int64 i = 0; i < default_color_table_length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of filling this out and then clearing it when context->num_inputs() == 3
, how about doing something like this:
- Define a utility function to create the default color table
namespace {
std::vector<std::vector<float>> DefaultColorTable(int depth) {
std::vector<std::vector<float>> color_table;
color_table.emplace_back({1, 1, 0, 1}); // yellow
color_table.emplace_back({0, 0, 1, 1}); // blue
...
if (depth == 1) {
...
}
return color_table;
}
} // namespace
- Change the kernel implementation to use the default table only if needed:
std::vector<std::vector<float>> color_table;
if (context->num_inputs() == 3) {
...
}
if (color_table.empty()) {
color_table = DefaultColorTable(depth);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Done.
OP_REQUIRES(context, colors_tensor.shape().dims() == 2, | ||
errors::InvalidArgument("colors must be a 2-D matrix", | ||
colors_tensor.shape().DebugString())); | ||
OP_REQUIRES(context, colors_tensor.shape().dim_size(1) == 4, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to require RGBA when depth is 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. The check has been updated. Now it requires the number of channels >= needed channels.
[0, 1, 0, 1], [0.5, 0, 0.5, 1], [0.5, 0.5, 0, 1], | ||
[0.5, 0, 0, 1], [0, 0, 0.5, 1], [0, 1, 1, 1], | ||
[1, 0, 1, 1]]) | ||
default_color_table = np.asarray([[1, 1, 0, 1], [0, 0, 1, 1], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about:
if colors is None:
# THIS TABLE MUST MATCH draw_bounding_box_op.cc
colors = np.asarray(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks.
@@ -85,9 +90,12 @@ def _testDrawBoundingBoxColorCycling(self, img): | |||
image = ops.convert_to_tensor(image) | |||
image = image_ops_impl.convert_image_dtype(image, dtypes.float32) | |||
image = array_ops.expand_dims(image, 0) | |||
image = image_ops.draw_bounding_boxes(image, bboxes) | |||
if colors is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be needed. We should be testing the draw_bounding_boxes
function exposed in the API instead of testing the generated wrappers. So, can't this be:
image = image_ops.draw_bounding_boxes(image, bboxes, colors=colors_arg)
?
Where colors_arg
points to the colors
value provided to _testBoundingBoxColorCycling
(i.e., before it was set to default_color_table
to generate test_drawn_image
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
return gen_image_ops.draw_bounding_boxes(images, boxes, name) | ||
|
||
@tf_export('image.draw_bounding_boxes', v1=[]) | ||
def draw_bounding_boxes_v2( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well keep the colors functionality in both V1 and V2, no?
Something like:
@tf_export('image.draw_bounding_boxes', v1=[])
def draw_bounding_boxes_v2(images, boxes, colors=None, name=None):
if colors is None and not compat.forward_compatible(2019, 05, 01):
return gen_image_ops.draw_bounding_boxes(images, boxes, name)
return gen_image_ops.draw_bounding_boxes_v2(images, boxes, colors, name)
@tf_export(v1=['image.draw_bounding_boxes'])
def draw_bounding_boxes(images, boxes, name=None, colors=None):
return draw_bounding_boxes_v2(images, boxes, colors, name)
We don't need separate wrappers for each of the generated functions.
Thoughts?
Where compat.forward_compatible
is from:
def forward_compatible(year, month, day): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
Thanks @asimshankar for the review. The PR has been updated. Please take a look. |
@yongtang Could you please look into the merging conflicts it has. Thanks ! |
26a231a
to
7ed8427
Compare
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
11fdea9
to
6629afb
Compare
Ping @hgadig to take a look. I rebased the PR as otherwise there is a merge conflict. Since the PR has been approved, wondering if there is anything else from that needs to be done? Would like to see this PR land soon. |
I do not see any approved(green tick mark) sign yet. Unless it is shown, I cannot proceed with the next steps. |
Thanks @hgadig for the help. I think @alextp already approved at one point. However, since there were merge conflicts, I rebased and pushed the PR several times. With the rebase, the approval comments were overridden. @alextp Could you take a look to see if everything is ok, and re-approve if it is fine? |
Nagging Reviewer @jaingaurav, @asimshankar: You have been added as a reviewer to this pull request. Please add your review or reassign. It has been 14 days with no activity and the |
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
6629afb
to
fbcc59c
Compare
PiperOrigin-RevId: 242188454
This fix tries to address the issue raised in #15692 where
it was not possible to specify the colors for boxes in
tf.image.draw_bounding_boxes
. Instead, a predefinedfixed color table was used to cycle through colors.
This fix adds
colors
Input toDrawBoundingBoxexV2
so that it is possible to specify the color. In case
no color is specified, the default color table will
be used.
Since there is an API change, the op is labeled as V2.
This fix fixes #15692.
Signed-off-by: Yong Tang yong.tang.github@outlook.com