pythonpython-3.xopencv

How can I set OpenCV to use origin as bottom-left corner of image?


Is it possible to set OpenCV to use the bottom-left corner of the image as the origin?

I'm using cv2.imshow() to display an image in a window that allows me to click on the image and get coordinates on mouseclick events. I can use part of the answer from this question to get the image displayed how I would like it (inverted on the x-axis) however when I click on the image to retrieve coordinates the origin is still in the top-left corner of the image.

import cv2 # Version 3.4.5
import imutils as im
import numpy as np
import matplotlib.pyplot as plt

list_of_coords = []
def store_mouse_coords(event, x, y, flags, params):
    global list_of_coords
    if event == cv2.EVENT_LBUTTONDOWN:
        list_of_coords.append((x, y))
        print(list_of_coords[-3:])
    return list_of_coords

def select_points_on_im(image, window_name='Select points'):
    image = image.copy()
    image = image[::-1, :, :]
    while True:
        cv2.namedWindow(window_name)
        cv2.setMouseCallback(window_name, store_mouse_coords)
        cv2.imshow(window_name, image)
        #plt.imshow(window_name, image, plt.gca().invert_yaxis,plt.show())
        key = cv2.waitKey(0) & 0xFF
        if key == ord("q"):
            break
    cv2.destroyAllWindows()
    return

select_points_on_im(image)

The line commented out line plt.imshow(window_name, image, plt.gca().invert_yaxis,plt.show()) is what I'd like to acheive but using imshow from OpenCV so that I can use is with my callback function. I'm using Python3 and OpenCV version 3.4.5.


Solution

  • Based on Mark Setchell's comment, I added the line adj_y = image.shape[0] - y to the mouse callback to achieve the desired behaviour. A small gotcha that confused me for a while, the shape attribute from numpy returns rows, cols- i.e. y, x:

    list_of_coords = []
    def store_mouse_coords(event, x, y, flags, params):
        global list_of_coords
        if event == cv2.EVENT_LBUTTONDOWN:
    
            adj_y = image.shape[0] - y # adjusted y
            print('image shape is {}'.format(image.shape[:2]))
            print('y was {}, image height minus y is {}'.format(y, adj_y))
            list_of_coords.append((x, adj_y))
        return list_of_coords