35

Is there an OpenCV function to draw an image over another image? I have one big image of Mat type. And I have a small image of Mat type (5x7). I want to draw this small image over the big image at specified coordinates.

Leo
  • 37,640
  • 8
  • 75
  • 100
vitaly
  • 463
  • 1
  • 5
  • 7
  • 11
    Please accept some of answers or tell why they do not work. Try not to keep this place open questions graveyard. – Tõnu Samuel Apr 18 '13 at 03:42

4 Answers4

56

Use Mat::rowRange() and Mat::colRange() to specify the area to which you want to draw in the destination Mat. Code:

Mat src( 5,  7, CV_8UC1, Scalar(1)); // 5x7
Mat dst(10, 10, CV_8UC1, Scalar(0)); // 10x10

src.copyTo(dst.rowRange(1, 6).colRange(3, 10));

Results in the following:

before copyTo():

dst:
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )

after copyTo():

dst:
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 1 1 1 1 1 1 1 )
    ( 0 0 0 1 1 1 1 1 1 1 )
    ( 0 0 0 1 1 1 1 1 1 1 )
    ( 0 0 0 1 1 1 1 1 1 1 )
    ( 0 0 0 1 1 1 1 1 1 1 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
    ( 0 0 0 0 0 0 0 0 0 0 )
Daniel S.
  • 6,458
  • 4
  • 35
  • 78
Eran W
  • 1,696
  • 15
  • 20
  • 2
    `a.copyTo(big.colRange(51,55).rowRange.(63,69))` for `5x7` – Nikson Kanti Paul Jun 12 '12 at 07:27
  • 2
    I've edited the complete thing so it gets clearer, because there were multiple problems with this answer: the indices were incorrect (those posted by @NiksonKantiPaul were both 1 too small in the range size), rowRange and colRange were swapped and there was another syntax problem. It should do nicely now. – Daniel S. Oct 01 '14 at 17:29
44

Create a Region Of Interest within the big image and then copy the small image to that region:

cv::Rect roi( cv::Point( originX, originY ), cv::Size( width, height ));
cv::Mat destinationROI = bigImage( roi );
smallImage.copyTo( destinationROI );

If you are certain the small image fits into the big image then you could simply do:

cv::Rect roi( cv::Point( originX, originY ), smallImage.size() );
smallImage.copyTo( bigImage( roi ) );
Rodrigo
  • 1,253
  • 16
  • 11
  • 2
    This unfortunately does not seem to work for me, I get the error: `error: no matching function for call to ‘cv::Mat::copyTo(cv::Mat)’. And it offers candidates receiving cv::OutputArray instead, when I look at http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#cv-mat-copyto it does seem to take Mat as an argument, yet I get this error? – pbond Aug 05 '13 at 14:17
5

Here is the solution in java version of openCV

Rect roi= new Rect(originX,originY,smalImage.width(),smallImge.height());
smallImage.copyTo( new Mat(input,roi) );
J.E.Tkaczyk
  • 557
  • 1
  • 8
  • 19
0
void zoomImage(Mat &src, Mat &dst, int scale_percent)
{

    //# percent of original size
    int width = int(src.cols * scale_percent / 100);
    int height = int(src.rows * scale_percent / 100);
    Size dim = Size(width, height);
    //pyrUp(tmp, dst, Size(tmp.cols * 2, tmp.rows * 2));
    resize(src, dst, dim, 0.0, 0.0, INTER_CUBIC);

    if (scale_percent < 100)
    {

        Mat srcR =Mat::zeros(Size(640,480),src.type()) ;
        int rstart = (src.rows - height) / 2;
        int rend = height;
        int cstart = (src.cols - width) / 2;
        int cend = width;
        dst.copyTo(srcR.rowRange( rstart, dst.rows+ rstart).colRange(cstart,dst.cols+ cstart));
        dst = srcR.clone();

    }
    else
    {
        Mat  ROI(dst, Rect((width - src.cols) / 2, (height - src.rows) / 2, src.cols, src.rows));
          dst = ROI.clone();
    }

}
Milind Morey
  • 2,100
  • 19
  • 15