Mouse callback event flags in python/opencv/OSX?

2019-06-11 14:30发布

I'm using OpenCV in python on OSX(10.10.5). I'm just starting out, so I may have made a silly mistake here. However, I haven't found anything that addresses this issue.

I have a mouse callback function that makes a list containing the coordinates of each point that is clicked on in a loaded image.

Now I'd like to use the flags in the mouse callback function to control whether I append coordinates to the list or whether I instead append "NA,NA" (e.g. if a point is missing from an image, I could hold the shift key and click on the image, and a placeholder would be appended instead of coordinates).

Although the "event" part of the mouse callback works*, the "flags" information doesn't seem to be available.

Here's the mouse callback function:

img_points = []

def write_points(event, x, y, flags, param):
    global img_points
    if event == cv2.EVENT_LBUTTONDOWN and flags != cv2.EVENT_FLAG_SHIFTKEY:
        img_points.append((x,y))
        print img_points
    elif event == cv2.EVENT_LBUTTONDOWN and flags == cv2.EVENT_FLAG_SHIFTKEY:
        img_points.append(('NA','NA'))
        print img_points

I've tried different versions of this, and as far as I can tell the problem is that the event_flag_shiftkey (or any other event_flag information) isn't available to the function.

Here's what happens if I alter the code in different ways:

-If I don't include anything about flags, the coordinates of every point that is clicked on are appended to img_points, so the event part seems to be ok.

-If I use the function as written above, the coordinates of every point that is clicked on (regardless of whether the shift key is pressed) are appended. So flags != cv2.EVENT_FLAG_SHIFTKEY must always be true.

-If I use the code as written above, but replace flags != cv2.EVENT_FLAG_SHIFTKEY with, say, flags == cv2.EVENT_FLAG_CTRLKEY, then nothing happens when I click regardless of whether I'm holding any buttons. That would suggest that regardless of what I do with the keyboard, flags == cv2.EVENT_FLAG_CTRLKEY and flags == cv2.EVENT_FLAG_SHIFTKEY are both always false.

Any ideas what is wrong here? Am I using event flags incorrectly? Is it a problem with the way OSX encodes keys/right clicks? How can I fix it?

*Additional note: actually, the event EVENT_LBUTTONDOWN is the only event that works. Similar to this post, EVENT_RBUTTONDOWN and the double click events don't work. (A double click registers as two clicks and appends two sets of coordinates). I've tried this both with the trackpad and with an external mouse. (The answer to the other post didn't solve the issue).

3条回答
做自己的国王
2楼-- · 2019-06-11 15:23

Actually you need to do a bitwise and (&) because the button flag and key flag are added (E.G. EVENT_FLAG_LBUTTONDOWN = 1 plus EVENT_SHIFTKEY = 16) yields a flag value of 17, so as an example to capture a double left mouse click while the Control key is pressed you need;

if event == cv2.EVENT_LBUTTONDBLCLK and (flags & cv2.EVENT_FLAG_CTRLKEY):

查看更多
迷人小祖宗
3楼-- · 2019-06-11 15:30

I had a similar issue and a simple print statement debugging helped me out.

I recommend to print the "flags" value you are getting and compare with the value stored in cv2.EVENT_FLAG_SHIFTKEY.

In my case, I am using Windows 7 opencv 2.4.9 and cv2.EVENT_FLAG_ALTKEY is 32L but the actual flags parameter returned is 33.

Similarly, cv2.EVENT_FLAG_CTRLKEY stores 8L but I get 9 for flags param. So, probably there are some bug in cv2 interface. Likely, the Mac version too.

(edit) 2.4.12 seems to have fixed this issue already.

查看更多
Root(大扎)
4楼-- · 2019-06-11 15:32

I know this is an old question, but I just got this to work and thought I'd share my solution:

I think the way flags register a shift click is not using just the flag by itself, but you also need to add the flag for the click. What I mean is you need to use:

flags == (cv2.EVENT_FLAG_SHIFTKEY + cv2.EVENT_FLAG_LBUTTON)

rather than just

flags == cv2.EVENT_FLAG_SHIFTKEY

This worked for me.

That said, I could also not get

events == cv2.EVENT_RBUTTONDOWN

to work on MAC OS X.

Hope this helps!

查看更多
登录 后发表回答