OpenCv cvRemap with variable image "subregion"

310 views Asked by At

I have an application which uses cameras that have an "aoi" feature. Similar to openCv's ROI function, the cameras allow specification of rectangular subset (call it "subregion") of the total sensor image to be acquired.

Using the aoi feature in the camera is preferable to doing ROI and copy operations in openCv. The bandwidth required to get a subregion of the image sensor data is reduced which means higher frame rates possible. Reduced pixel counts also reduces CPU burden.

The application can optionally do undistort using a camera calibration matrix. I only want to do the camera calibration once (or at least not every time I redefine the camera aoi).

The undistort works fine, when the camera's aoi is set to the full image. But, I'm having trouble getting it to work when I use a reduced aoi in the camera. Black lines appear at the bottom of the undistorted images.

I thought I could make a copy of the mapx and mapy data like this:

cvSetImageROI(mapx,aoi_box);
mapx_aoi = cvCreateImage(cvSize(sensor_width,aoi_box.height), IPL_DEPTH_32F, 1 );
cvCopyImage(mapx,mapx_aoi);

cvSetImageROI(mapy,aoi_box);
mapy_aoi = cvCreateImage(cvSize(sensor_width,aoi_box.height), IPL_DEPTH_32F, 1 );
cvCopyImage(mapy,mapy_aoi);


cvResetImageROI(mapx);
cvResetImageROI(mapy);

Where aoi_box is what was sent to the camera to define it's ROI. The undistortion is done with cvRemap:

I thought this should extract the correct offsets for remapping each pixel in the camera's subregion. But, the resulting undistorted image has black lines at the bottom of the image. When the subregion is near the top (small y), I only have a few black lines. When y gets bigger, I get more black lines. At some value of y, the entire undistorted image is black.

Probably something similar would happen on the right side of the image, but I always use the full width of the image and only narrow the height and y position of the subregion.

if (undistort_images)
{
    cvCvtColor(multiframe_images[0],distorted_image , CV_BayerBG2BGR);
    cvRemap(distorted_image,image,mapx_aoi,mapy_aoi);
}
else 
{
    cvCvtColor(multiframe_images[0],image , CV_BayerBG2BGR);

}

Any hints on why this doesn't work correctly?

Thanks

Edit:

I've benn looking at the undistorted images more closely and noticed that the undistorted image has a -y offset that appears to match the y of the subregion. That offset causes the black lines, since that many lines will be missing from the subregion image.

For example, if the subregion was for 100 lines starting at y = 50, I see only the bottom 1/2 of the images (50 lines), shifted up.

So, I think I see how I could "fix" the issue by applying an offset to mapy_aoi, but I don't understand why that's required.

1

There are 1 answers

0
Dave Thomas On

Turns out the map images don't contain pixel offsets, but absolute pixel locations.

So, rather than trying to use a subset of the maps, I decided to regenerate them from the intrinsics and distortion coefficients each time the camera aoi was changed.