Adapting cv2.warpAffine() from Integer Corners to Integer Centers Convention


I’m currently working on a project where I’m using the Integer Corners convention, which means that the origin (0,0) is situated at the top-left corner, and the center of the top-left pixel is represented as (0.5,0.5).

I need to use the cv2.warpAffine() function in order to crop and rescale an image. I’ve read that cv2 follows the Integer Centers convention, with the origin (0,0) at the center of the top-left pixel.

What pre-processing and post-processing steps I should apply to align the two conventions correctly?

Thank’s for your help !!

sampling at pixel centers is the only sane way. everyone samples at pixel centers.

the “difference” is that opencv, along with the entire world, puts integer coordinates at pixel centers.

an image consists of pixels. pixels have extent. the picture ranges from the outer corners of the outer pixels.

cv::resize() maps corners to corners. warpAffine() goes strictly by the matrix. that is the only difference you need to respect.

when calculating the transform matrix, you need to incorporate translations and scalings properly.

if you need help, show your attempt.

According to this article :

it’s a good practice in computer vision systems to always use coordinates rather than indices to represent geometries , such as boxes and polygons. This is because indices are integers, and can easily lose precision during geometric operations. Using indices for bounding boxes has caused some issues in Detectron.

The dataset I use are built on Integer Corners convention and I am obliged to respect this convention, so I don’t have the possibility to switch to integer center convention and align to opencv.

Specifically, here is the code I use to crop and rescale :

import numpy as np
import cv2

new_size = 224
bounding_box_size = max(bb_bottom - bb_top, bb_right - bb_left) 
factor = new_size / bounding_box_size 
cx = (bb_left + bb_right) / 2
cy = (bb_top + bb_bottom) / 2
M = np.concatenate((Identity, [[-cx], [-cy]]), axis=1) * factor
M[:, 2] += new_size / 2
M = np.concatenate((M, [[0, 0, 1]])) 

img_crop = cv2.warpAffine(image, M, (new_size, new_size)) 

To verify, I want to compute the corresponding pixels in the original image of all pixels in the crop (224,224) . Should I subtract (0.5,0.5) from all ?