How to split OpenCV matrix while retaining continuity?

Viewed 87

I am trying to make a visual odometry algorithm work in real time (using my stereo camera). The camera feed gets returned as a single image (i420 pixel format), where I have to manually split the image into a left and right frame. One of the problems that I am running into is when I call cv::triangulatePoints. The function gives me an error saying that the input matrices (meaning the left and right frame) are not continuous.

When I receive the input image from the camera, using:

// Read camera feed
IMAGE_FORMAT fmt = {IMAGE_ENCODING_I420, 50};
BUFFER *buffer = arducam_capture(camera_instance, &fmt, 3000);
if (!buffer) 
    return -1;

// Store feed in image
cv::Mat image = cv::Mat(cv::Size(width,(int)(height * 1.5)), CV_8UC1, buffer->data);
arducam_release_buffer(buffer);

// Change image to grayscale (grayscale increases FPS)
cv::cvtColor(image, image, cv::COLOR_YUV2GRAY_I420);

if (!image.isContinuous())
    std::cout << "image is not continuous" << std::endl;

The image passes the continuity check fine (meaning the image is continuous).

However, after I resize and split the image into a left and right frame, using:

double scale_factor = 640.0 / width;
int custom_width = int(width * scale_factor);
int custom_height = int(height * scale_factor);

// OpenCV resize
cv::Mat frame = cv::Mat(cv::Size(custom_width, (int)(custom_height * 1.5)), CV_8UC1);
cv::resize(image, frame, frame.size(), 0, 0);
        
// Split image into left and right frame
cv::Mat frame_left = frame(cv::Rect(0, 0, custom_width / 2, (int)(custom_height * 1.5)));
cv::Mat frame_right = frame(cv::Rect(custom_width / 2, 0, custom_width / 2, (int)(custom_height * 1.5)));

if (!frame.isContinuous())
    std::cout << "frame is not continuous" << std::endl;
if (!frame_right.isContinuous())
    std::cout << "right frame is not continuous" << std::endl;
if (!frame_left.isContinuous())
    std::cout << "left frame is not continuous" << std::endl;

The resized image (frame) is continuous, but the left and right frames fail the continuity check (meaning they are not continuous).

So I guess my question is how can I split the image into two different images, while keeping them continuous?

1 Answers

The solution to this problem is actually quite simple:

if (!frame_right.isContinuous()) {
                frame_right = frame_right.clone();
if (!frame_left.isContinuous()) {
                frame_left = frame_left.clone();

By using the clone() function, you can copy the image and OpenCV will consider it to be a new image. This way the right and left frames will retain continuity (or be set to continuous status).

So splitting the image destroys continuity and cloning will restore continuity.

Related