Skip to content

Support CV_CAP_MODE_GRAY in FFMPEG backend#9123

Closed
cristiklein wants to merge 3 commits intoopencv:3.4from
cristiklein:gray-in-ffmpeg
Closed

Support CV_CAP_MODE_GRAY in FFMPEG backend#9123
cristiklein wants to merge 3 commits intoopencv:3.4from
cristiklein:gray-in-ffmpeg

Conversation

@cristiklein
Copy link
Copy Markdown

This pullrequest changes

This pullrequests adds support for CV_CAP_MODE_GRAY in the FFMPEG videoio backend. This is particularly beneficial for applications that only care about the luminance, such as feature detection. Without this features wasteful conversion might happen, e.g., FFMPEG backend converts video from YUV to RGB then application uses cvtColor to convert frame to gray, although this information is already available in the Y channel.

@peters
Copy link
Copy Markdown
Contributor

peters commented Jul 10, 2017

@alalek 👍

@paroj
Copy link
Copy Markdown
Contributor

paroj commented Jul 12, 2017

you should rather use CAP_PROP_FORMAT. see #5485

@cristiklein
Copy link
Copy Markdown
Author

Thanks @paroj for your feedback. I went through #5458 and I am confused. The proposal mentions CAP_PROP_CONVERT (not CAP_PROP_FORMAT), but there is no mention thereof in the nightly documentation: http://docs.opencv.org/master/d4/d15/group__videoio__flags__base.html#gaeb8dd9c89c10a5c63c139bf7c4f5704d

Also, I looked at CAP_PROP_FORMAT, but the documentation does not explain how a user is supposed to use this property to set grayscale output. I quickly checked the V4L2 source code and setting this property is not supported.

Can you clarify how I should proceed?

@paroj
Copy link
Copy Markdown
Contributor

paroj commented Jul 12, 2017

yes, CAP_PROP_CONVERT has unfortunately been only discussed so far and not implemented.

  1. turn off CAP_PROP_CONVERT_RGB (default value is true, that means BGR)
    • if source file is grayscale this should be sufficient
  2. set CAP_PROP_FORMAT to AV_PIX_FMT_GRAY8 for grayscale conversion
    • alternatively set CAP_PROP_FOURCC to (G,R,E,Y) to be backend agnostic. This is what cap_v4l uses. However with ffmpeg it will require some logic to map to AV_PIX_FMT_GRAY8. As a bonus this would match the VideoWriter API.

@cristiklein
Copy link
Copy Markdown
Author

Thank you for the clarification. Let me give you my opinion about your suggestion:

  1. Setting CAP_PROP_FORMAT to AV_PIX_FMT_GRAY8 is sub-optimal for two reasons: First, it requires the user to import an FFMPEG header to have access to the constant. Second, as somebody already mentioned in fix zero length std::string in putText() #5458, grayscale is very common in computer vision, hence it would be desirable to make this setting backend-neutral. As a user, I would very much appreciate writing the same code both for V4L2 in production and FFMPEG in unit testing.

  2. CAP_PROP_FOURCC is already used by FFMPEG to retrieve the codec of the input video. Giving it different semantics for setting than for getting would be confusing, whereas changing the API and using it for setting "desired output format" feels wrong to me.

Do you feel there are other good options except CAP_PROP_CONVERT? I could certainly dedicate some time and implement that for the FFMPEG backend, but given the larger effort, I would rather wait for some momentum to build around it.

@paroj
Copy link
Copy Markdown
Contributor

paroj commented Jul 13, 2017

unfortunately there is no backend neutral property to achieve this right now. That is exactly why CAP_PROP_CONVERT is needed.

You could let CAP_PROP_CONVERT_RGB=false imply grayscale for FFMPEG, but that would obviously not work for V4L and generally make the situation worse. So I am afraid CAP_PROP_CONVERT is the only clean solution.

@vpisarev
Copy link
Copy Markdown
Contributor

@cristiklein, thanks for the contribution! I do not see how the newly added FFMPEG enum values (which are declared in the internal header) relate to the public API. It's quite unsafe solution because we can easily end up with unsynchronized values and then we get very weird results or crashes

@cristiklein
Copy link
Copy Markdown
Author

@vpisarev, I couldn't agree more! However, if you look at the FFMPEG enum values, they are all unrelated to the public API and can easily end up unsynchronised. Hence, I simply opted for maintaining the existing "style" hoping that that would make my patch more acceptable.

I think we both agree that a proper solution would entail making all FFMPEG enum values relate to their public counterpart.

@alalek
Copy link
Copy Markdown
Member

alalek commented Sep 29, 2017

I believe because standalone ffmpeg wrapper can't use OpenCV's public API headers without additional refactoring (split enums from others things).

@asenyaev
Copy link
Copy Markdown
Contributor

asenyaev commented Apr 7, 2021

jenkins cn please retry a build

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.

8 participants