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
fixing waitKey commands to be universal #7105
fixing waitKey commands to be universal #7105
Conversation
Hmm seems it is not working like expected ... |
int c = waitKey(0); | ||
if( c == 27 || c == 'q' || c == 'Q' ) | ||
int c = waitKey(0) & 0xFF; | ||
if( c == 27 || c == ord('q') || c == ord('Q') ) |
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.
ord() only exists in python (and imho, no further conversion needed here)
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.
Hi berak. Discovered that C indeed does not have the ord function. As to the conversion. I read somewhere that 'char' gives problems when placed in an into when values larger then 127 occur. Not sure why though!
All fixing done! |
Oops - kind of screwed stuff up it seems :( my ord fixes are gone. Will reapply them. |
👍 |
@terfendail I guess you are new to the team? If so welcome! Haven't seen you around yet! |
I believe it will be good to reduce magic code.
|
I agree that the magic code is maybe a bit weird, but people are so used to using the waitKey interface, as it is documented everywhere on the wide web, that adding a new function will only raise more questions in my opinion. It will also generate a flood of questions in my experience I guess adding a function specific for this is a bit overkill? |
|
||
if( (char)c == 27 ) | ||
if( c == 27 ) |
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.
Original PR fixes warning (compare int and char), which is added back by changes like these.
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.
But why would this generate a warning? Buildbot builds samples and there is not a single one out there. If c is an int, then comparing it to 27 or to any other numerical value should work just fine in all C++ standards. Could you elaborate where this could go wrong?
Just destroyed the extra addons by @terfendail but will add em back manually. Gimme a sec! |
@alalek I just continued some research about this. I have locally built OpenCV + OpenCV examples, with noisy warnings enabled, so that basically everything gets outputted. When checking up on the output, there wasn't a single issue reported on comparing ints and chars in this way. Neither did building the samples manually inside a IDE trigger any warnings. Can you tell me how I could reproduce those warnings? |
Oh btw, the only, somewhat relevant error I was able to dig up the WWW, is when comparing an integer to a char pointer. But since we have no pointer comparisons here, those risks are not the case here. |
I assume that author of #7098 capture some noise warning about this, possible from some static analyzer. |
@yyyhssss Can you please explain how you got those noisy errors and check if my version of the code still generates those? Because I am not finding any way of generating those. @alalek But if the most common compilers do not cover this issue, shouldnt we then keep everything universal? I am afraid this is only applicable in some very perticular cases. |
Just to add, the static analyzer cppcheck does not report anything on Ubuntu 14.04 when testing a sample. |
@@ -453,7 +453,7 @@ int main() | |||
|
|||
for(;;) | |||
{ | |||
char key = (char) waitKey(0); | |||
int key = waitKey(0) & 0xFF; | |||
|
|||
if(key == 'd' && flag3 == 0) |
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.
@StevenPuttemans , @alalek don't you think that after making c
of type int
this comparison can be true
or false
depending on the signed
or unsigned
char
type default? (I mean the case when the symbol code is more than 127? for 'd'
it will work anyway!)
I would prefer leaving char
type for c
...
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.
Hi @apavlenko, I guess I am missing what you are trying to say here. Could you explain where you would like in INT cast to ensure that we have no loss of values above 127? Or am I completely missing your point?
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.
I mean that the int key = waitKey(0) & 0xFF;
is always non-negative, while char
constant ('*'
) can be negative when the char
type is signed
and the symbol ASCII code is more than 127 - do you agree?
But in reality people will unlikely use regional-specific symbols is such case, so the issue is minor.
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.
Hmm I get your point and agree, but isn't it best to serve a solution that tends to mass?
Maybe we should add a notice somewhere covering this special case?
@terfendail it seems you made a remark but it is not showing on github. Can you readd it? |
My previous comment adds nothing to @apavlenko reply that's why I removed it. Existing discussion more an more persuade me that separate function as suggested by @alalek would be the best decision. It could be a place to describe possible issues and it could be tuned as necessary to avoid as much issues as possible.
@StevenPuttemans @apavlenko @alalek What's your opinion on this? |
I do get that we need a universal solution, but already explained above why I am not in favor for new functionality to wrap this. That being said, it kind of makes sense to change all this to make it more uniform, just be prepared for a shitload of |
Also, I will hapily implement the suggestion, but probably be by the beginning of next week. Got a deadline to catch here ;) |
@terfendail I guess the reason why this is crashing, is due to some master samples being update in the time between? |
As I was afraid: #6945 introduced changes that shifted lines in the docs... I am not sure what would be the fastest way to solve these conflicts without all the edits did by me... |
I squashed commits and will now see if I can cherry pick that commit onto a new branch |
Did a cherry pick to a new branch on top of recent master, solved conflicts and changed name locally then pushed it back. Should work now! |
Okay so applying the suggested static inline function results in Will take a look at possible solutions! |
@@ -95,7 +95,7 @@ Explanation | |||
|
|||
line( image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8 ); | |||
imshow( window_name, image ); | |||
if( waitKey( DELAY ) >= 0 ) | |||
if( (waitKey( DELAY ) & 0xFF) >= 0 ) |
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.
@terfendail in case like this, do we also prefer use of waitChar?
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.
It looks for me as a "press any key" wait so may be we even doesn't have to check the last significant byte only.
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.
Well yeah it does, but ofcourse, then they could simply have used waitKey() right? maybe I should dig into the actual sample to get an understanding of that DELAY parameter
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.
Processing looks like some animation with DELAY time between frame changes which could be immediately halted by pressing of any key.
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.
Hmmm in fact the 0xFF here is not needed, simply because it has to be any
key. Will remove the 0xFF in these cases to not make the code more complex then needed. Basically waitChar should be used if 0xFF is needed, else the 0xFF can go!
Ok so basically it runs all smooth now. @terfendail how could we expand waitChar() to always return a -1 when the timer runs out? This is the one thing I would prefer instead of letting it be system specific... |
BTW, "char" type can be unsigned on some platforms, so there is no chance to return -1 in general way. |
Okay not a general way, but taking a look at the code, we already check if signed and unsigned on the CHAR definition are equal to define if the system has signed or unsigned char. So we could also provide solutions for each platform ensure that -1 is returned right? |
So with the following code, and having a
My system outputs perfectly fine the f when pressed, but when waiting 10 milliseconds this comes out
which basically means that the 255 value gets scrambled into something untranslatable. For my kind of system this can be solved by adding a simple conditional loop.
Which outputs -1 if I wait enough. Can anyone check on the other type of system, if anyone is around, that this works for you guys? |
At the moment I see no way to return -1 on unsigned char platforms. Since the system expect that return value is unsigned it will treat every received number as positive regardless of the internal representation so it will never consider it as "-1". We could change function behavior to return either value we want but it have to be positive. Of course there is decision to explicitly change return value to signed char but it will hurt value comparison for the whole high part of ASCII table(however it will be at least marked with warning by most of modern compilers) |
What is about these return values:
Also we can swap first two positions ( |
Guys I want to wrap some things up here ... because basically this doesn't seem to lead to any final stage and it is starting to grow more and more like some sort of hidden monster inside OpenCV ... So
I get that we want to get an interface that suits everyone his needs, but by now I have overhauled the 100 files for about 10 times, and I am not going to do it further until there is a consensus on these points :) As far as I see it, the original PR, keeping the int enforcing and adding 0xFF overall seemed fine. I do get the value of a waitChar to remove those 0xFF because new users tend to get lost in those ... but why not simply do that inside the original waitKey() function instead of providing new functionality. Let the discussion start! |
I definitely have to agree that this discussion looks like architecture debate rather than fine tuning of the final fix. So from my point of view:
|
I agree to this. And combining with your point 4, this seems indeed valid to keep the function.
You completely lost me there 💃 |
Regarding question 3 I've tried to notice that waitKey() is able to select key codes depending on selected input language. So if user select language which alphabet contains special characters(i.e. vowels with umlauts) or is completely different from Latin then return values for character keys will be greater than 127. As far as I know it is the only case for return values greater than 127 and so the only case to bother about char variable sign. |
I get the impression that the others kind of left the discussion ... I would still urge @alalek @apavlenko to get back and defend their positions before moving further. @terfendail regarding to your last post. Indeed the only problem will arise with regional special chars. Therefore I suggest to limit the use of waitChar to the 0-127 range and add this as a not. It is fairly straightforward that programmers to not use regional specific chars, just to avoid their software not being managable outside their region, so I guess limiting it won't do so much harm. In that idea, we could just quit thinking about the whole signed/unsigned char discussion and move back to the int idea ... which seemed far more reasonable to me... |
My another suggestion is to create a poll (or set of pools) via issues tracker with votes via "GitHub reaction" button. I'm not sure that all results will be fully accepted, but it is a great feedback anyway. |
I agree that polling the community for its opinion could help, but lets be straight here, how many people do we actually expect to reply? If I see how low the number of interactive users is on here, and on the forum, then how will we have a valid representation of the communities opinion? |
There is related proposal how we can do this: master...alalek:waitKey It works fine on example with MSVC compiler on debug/release builds (and with/without "define"). |
@alalek I kind of like your proposition. But we should drop the inline code. Inline code cannot be wrapped around for the python wrappers, which can be solved by seperating implementation and declaration into .hpp and .cpp files. |
Sorry for keeping silence! |
@apavlenko thanks for the reply! @alalek, I noticed you are adding a PR yourself (#7190) with your suggested fix. This makes me wonder why I am keeping this open and even try to put in effort to get to a concensus? For now I will close it down, let you guys decide for what you want. If you want to use the branch to cherry pick changes from, go ahead, I will leave it open on my repo. @terfendail It seems @alalek decided to test his approach, guess the discussion on how to proceed is between you guys now. |
@StevenPuttemans #7190 is added to check Python bindings builds (with "inline"). It works fine (but has some ABI problems on Linux). I'm not going to update mentioned PR actually. |
@alalek I will get back to you with some pointers on the inline thing at the other PR |
So it looks like we've came to decision to retain Decision Pros:
Decision Cons:
Have I missed something? |
@StevenPuttemans, we've discussed this problem and the proposed solution with the team. The proposed solution is to modify cvWaitKey()/cv::waitKey() behaviour so that it always applies int cvWaitKey(int delay) { return cvWaitKeyEx(delay) & 255; } Later on cvWaitKeyEx() can further be modified (without changing API) to return some universal, cross-platform codes for arrows and other special keys regardless of backend. Rationale and benefits of the proposed solution:
the downside is that 1% of samples/apps that react on special keys will need to be modified, but that's should be easy to detect and fix. What do you think? If you agree, shall we close this PR and submit a smaller one with the proposed fix? |
@vpisarev I guess I can agree to that if the whole team is behind that decision! However, I am about to leave for a CV conference until next monday, so if anyone has the time to provide the supposed fix in the meanwhile, do go ahead! |
thanks! have a nice trip to conference! |
@vpisarev thanks! The conference was quite nice. Kind of a busy week now, but the week after that should contain time to provide the fix! |
As a follow up for the discussion held in PR #7098, and the discussion started in this topic, we decided to implement a waitChar function that always returns the correct value if the returned value is needed for further comparison to ASCII codes of char inputs.