1

A pretty simple concept, I have a 640x480 Mat and a 800x480 screen, so I am trying to copy the original image to the center of a black 800x480 image so the aspect ratio is maintained but the whole screen is used.

I followed this post and tried both solutions (direct copy to and region of interest) and get the same error:

OpenCV Error: Assertion failed (0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols) in Mat, file /home/pi/opencv-3.0.0/modules/core/src/matrix.cpp, line 464
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/pi/opencv-3.0.0/modules/core/src/matrix.cpp:464: error: (-215) 0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols in function Mat

Aborted

The offending code:

cv::Mat displayimage = cv::Mat(800, 480, CV_16U, cv::Scalar(0));
modimage1.copyTo(displayimage.rowRange(1,480).colRange(81,720));

I first attempted it with start/end range/row of (0,480) and (80,720), but then the error made it sound like it couldn't start at 0, so then of course I thought I was off by 1 and I started at 1 with the same results. But in actuality, the error is for the COLUMNS and not the ROWS, and with the columns being off by 1 wouldn't even matter. So what doesn't it like about where I'm trying to copy this image to?

Community
  • 1
  • 1
DrTarr
  • 922
  • 2
  • 15
  • 34

2 Answers2

2

Duh, this one was easier than I thought. The cv::Mat() arguments are height THEN width, not width then heigth. Tricky. But I also ran into an error with the wrong number of channels for my mat type, so to make the code bulletproof I just initialized it as the same image type of the image that would be copied to it, so the code below works fine:

cv::Mat displayimage = cv::Mat(480, 800, modimage1.type(), cv::Scalar(0));
modimage1.copyTo(displayimage.rowRange(0,480).colRange(80,720));
DrTarr
  • 922
  • 2
  • 15
  • 34
1

you can use cv::copyMakeBorder

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "iostream"

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
    Mat src = imread(argv[1]);
    if (src.empty())
    {
        cout << endl
             << "ERROR! Unable to read the image" << endl
             << "Press a key to terminate";
        cin.get();
        return 0;
    }

    imshow("Source image", src);

    Mat dst;

    Size dst_dims = Size(800,480);
    int top = ( dst_dims.height - src.rows ) / 2;
    int bottom = ( (dst_dims.height + 1) - src.rows ) / 2;
    int left = ( dst_dims.width - src.cols ) / 2;
    int right = ( ( dst_dims.width + 1 ) - src.cols ) / 2;

    copyMakeBorder(src, dst, top, bottom, left, right, BORDER_CONSTANT, Scalar(0,0,0));

    imshow("New image", dst);
    waitKey();

    return 0;
}
sturkmen
  • 3,495
  • 4
  • 27
  • 63