eomer
eomer

Reputation: 3574

Place an image on an image

I want to place an image on a captured video frame at the coordinates which I determined.

I asked that before and I have been told to use cvCopy and cvSetImageROI but I dont want to crop on those coordinates I want to add another image. Maybe it's the right way but I didn't understand it (if its right please explain it).

Upvotes: 7

Views: 18759

Answers (4)

Michał Jankowski
Michał Jankowski

Reputation: 427

Unfortunately the "Paul Lammertsma" code has mixed up indexes here you have fixed code:

void drawImage(IplImage* target, IplImage* source, int x, int y) {

    for (int ix=0; ix<source->width; ix++) {
        for (int iy=0; iy<source->height; iy++) {
            int r = cvGet2D(source, iy, ix).val[2];
            int g = cvGet2D(source, iy, ix).val[1];
            int b = cvGet2D(source, iy, ix).val[0];
            CvScalar bgr = cvScalar(b, g, r);
            cvSet2D(target, iy+y, ix+x, bgr);
        }
    }
}

Upvotes: 0

enthusiasticgeek
enthusiasticgeek

Reputation: 2736

void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location, CvScalar S, CvScalar D)
{
 int x,y,i;

  for(x=0;x < overlay->width -10;x++)     
//replace '-10' by whatever x position you want your overlay image to begin. 
//say '-varX'
    {
        if(x+location.x>=src->width) continue;
        for(y=0;y < overlay->height -10;y++)  
//replace '-10' by whatever y position you want your overlay image to begin.
//say '-varY'
        {
            if(y+location.y>=src->height) continue;
            CvScalar source = cvGet2D(src, y+location.y, x+location.x);
            CvScalar over = cvGet2D(overlay, y, x);
            CvScalar merged;
            for(i=0;i<4;i++)
            merged.val[i] = (S.val[i]*source.val[i]+D.val[i]*over.val[i]);
            cvSet2D(src, y+location.y, x+location.x, merged);
        }
    }
}

To use it

cvOverlayImage(largerimage, overlayimage, cvPoint(10, 10), cvScalar(0.5,0.5,0.5,0.5), cvScalar(0.5,0.5,0.5,0.5)); 
//The cvPoint(10,10) can be the cvPoint(varX,varY) depending on how you write the function 
//and how you want to use it. 
//You cannot choose values less than 'varX' and 'varY' in this case
//else you would see a runtime error.

Upvotes: 6

Paul Lammertsma
Paul Lammertsma

Reputation: 38252

You will have to copy pixel by pixel from the source to the destination. The code below does precisely that, offseting with coordinates x and y. I haven't actually tried this, but am fairly certain it should work more or less as you'd expect.

Just make sure the target image is at least the size of the source plus the offset!

void drawImage(IplImage* target, IplImage* source, int x, int y) {
    for (int ix=0; x<source->width; x++) {
        for (int iy=0; y<source->height; y++) {
            int r = cvGet2D(source, iy, ix).val[2];
            int g = cvGet2D(source, iy, ix).val[1];
            int b = cvGet2D(source, iy, ix).val[0];
            CvScalar bgr = cvScalar(b, g, r);
            cvSet2D(target, iy+y, ix+x, bgr);
        }
    }
}

Upvotes: 0

Ola
Ola

Reputation: 485

I did this a while ago using SetRoi, it was something like this. I have two images, one is a thumbnail called thumb_frame that is the small picture I will include in the large image show_frame

//I set the ROI to the same size as the thumb_frame
cvSetImageROI(show_frame.image, cvRect(thumbnail_x_pos,
                    thumbnail_y_pos, thumb_frame->width, thumb_frame->height));

//I add the image to the designated ROI
cvAddWeighted(thumb_frame, alpha, show_frame, beta, 0, show_frame);

That's about it.

Upvotes: 7

Related Questions