C++ 需要将一个图像复制到另一个图像ROI

C++ 需要将一个图像复制到另一个图像ROI,c++,opencv,image-processing,C++,Opencv,Image Processing,我正在尝试将一个图像层复制到另一个图像ROI。我的代码如下 Mat4b src= imread("path"); Mat3b dest = imread("path"); Rect roi = Rect(179,539,src.cols,src.rows); //src.cols = 1186 and src.rows= 1134 after scaling. Mat destinationROI = dest(roi); src.copyTo(destinationROI); imwrite(

我正在尝试将一个图像层复制到另一个图像ROI。我的代码如下

Mat4b src= imread("path");
Mat3b dest = imread("path");
Rect roi = Rect(179,539,src.cols,src.rows); //src.cols = 1186 and src.rows= 1134 after scaling.
Mat destinationROI = dest(roi);
src.copyTo(destinationROI);
imwrite("destinationROI.png", destinationROI);
输入src是 输入dest是

但是得到的输出是相同的dest图像。
然后我试图在复制之前保存destinationROI。我得到的结果是正确的。复制src也是可行的。但是它不会在dest映像中产生任何影响。

您的矩阵类型不匹配。一个有四个频道,另一个有三个。 显然,将4通道矩阵的内容复制到3通道矩阵是行不通的

不幸的是,在某些情况下,当OpenCV无法在旧内存上工作时,它会悄悄地返回到创建新矩阵的过程中。最有可能的情况就是这样。执行复制后,
destinationROI
开始指向新内存

请注意,您可以通过将
destinationROI
声明为
Mat3b
来防止这种行为。然而,为了使代码正常工作,源和目标都需要携带相同数量的通道


我在这里所做的两个假设都只是有根据的猜测,但我没有测试有问题的代码。

您的矩阵类型不匹配。一个有四个频道,另一个有三个。 显然,将4通道矩阵的内容复制到3通道矩阵是行不通的

不幸的是,在某些情况下,当OpenCV无法在旧内存上工作时,它会悄悄地返回到创建新矩阵的过程中。最有可能的情况就是这样。执行复制后,
destinationROI
开始指向新内存

请注意,您可以通过将
destinationROI
声明为
Mat3b
来防止这种行为。然而,为了使代码正常工作,源和目标都需要携带相同数量的通道


我在这里所做的两个假设都只是有根据的猜测,但是我没有测试有问题的代码。

您的代码太初始了。而且你的图像也不适合完美的结果。我猜你对图像执行了真代码,你会得到一个穿着衬衫的人的图像

Mat4b src= imread("path");// to load 4 channel image : imread("path",IMREAD_UNCHANGED); 
Mat3b dest = imread("path");
Rect roi = Rect(179,539,src.cols,src.rows); //src.cols = 1186 and src.rows= 1134 after scaling.
Mat destinationROI = dest(roi);
src.copyTo(destinationROI);
imwrite("destinationROI.png", destinationROI);

我可以写一个代码来获得下面的图像(它是经过Photoshop处理的,只是为了显示结果),但它对你们的图像来说毫无意义

编辑1:

我在这里编辑了你的代码。查看//编辑代码中的1,2,3

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>

using namespace cv;
using namespace std;

float sx, sy;
int tx, ty;

struct TaggingPoint{
int rshx, rshy;
int lshx, lshy;
int topx, topy;
int botx, boty;
}body_points, garment_points;

int main(int argc, char** argv)
{

Mat shirt;
Mat body;

shirt = imread(argv[1], IMREAD_COLOR);
if (shirt.empty())
return -1;

body = imread(argv[2], IMREAD_COLOR);
if (body.empty())
return -1;

body_points.rshx = 418;
body_points.rshy = 706;
body_points.lshx = 1234;
body_points.lshy = 706;
body_points.topx = 838;
body_points.topy = 510;
body_points.botx = 838;
body_points.boty = 1534;

garment_points.rshx = 239;
garment_points.rshy = 147;
garment_points.lshx = 755;
garment_points.lshy = 147;
garment_points.topx = 505;
garment_points.topy = 50;
garment_points.botx = 505;
garment_points.boty = 953;


// edit 1 : when you calculate by this values your shirt image's width will be greater that body image's width
// so to reduce it
sx = (float)(body_points.lshx - body_points.rshx) / (garment_points.lshx - garment_points.rshx)*0.995;
sy = (float)(body_points.boty - body_points.topy) / (garment_points.boty - garment_points.topy);

//scale the image
resize(shirt, shirt, Size(), sx, sy, INTER_LINEAR);

imwrite("shirt.png", shirt);

//translation happened
//  tx = body_points.rshx - (sx * garment_points.rshx);
tx = body_points.rshx - (garment_points.rshx);
ty = body_points.rshy - (sy * garment_points.rshy);

//draw one image over another image
//src.copyTo(dst.rowRange(1, 6).colRange(3, 10));
//  shirt.copyTo(body.rowRange(tx, shirt.rows).colRange(ty, shirt.cols));
//  shirt.copyTo(body.rowRange(100, 1000).colRange(100, 500));

//  cvtColor(shirt, shirt, CV_BGRA2BGR);
//  cvtColor(body, body, CV_BGRA2BGR);


namedWindow("body");
//Rect roi(cv::Point(tx, ty), Size(shirt.size()));

// Edit 2 : Rect.x = 0

Rect roi = Rect(0,ty,shirt.cols,shirt.rows);
Mat destinationROI = body(roi);
//  cvtColor(destinationROI, destinationROI, CV_BGRA2BGR);

// Edit 3 : Create a mask ( it is show purpose only, need improvement )
Mat mask;
cvtColor( shirt, mask, COLOR_BGR2GRAY );
mask = mask < 250;

shirt.copyTo(destinationROI,mask);

imwrite("destinationROI.png", destinationROI);

imshow("body", body);
imwrite("body.png", body);

waitKey();
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
浮子sx,sy;
int-tx,ty;
结构标记点{
int rshx,rshy;
int lshx,lshy;
int-topx,topy;
int-botx,boty;
}身体_点、服装_点;
int main(int argc,字符**argv)
{
垫子衬衫;
垫体;
衬衫=imread(argv[1],imread\u颜色);
if(shirt.empty())
返回-1;
body=imread(argv[2],imread\u颜色);
if(body.empty())
返回-1;
体_点rshx=418;
体_点rshy=706;
体_点lshx=1234;
体_点。lshy=706;
body_points.topx=838;
主体_点。topy=510;
body_points.botx=838;
body_points.boty=1534;
garment_points.rshx=239;
garment_points.rshy=147;
garment_points.lshx=755;
garment_points.lshy=147;
garment_points.topx=505;
garment_points.topy=50;
garment_points.botx=505;
garment_points.boty=953;
//编辑1:通过此值计算时,衬衫图像的宽度将大于身体图像的宽度
//所以要减少它
sx=(浮动)(body_points.lshx-body_points.rshx)/(garment_points.lshx-garment_points.rshx)*0.995;
sy=(float)(body_points.boty-body_points.topy)/(garment_points.boty-garment_points.topy);
//缩放图像
调整大小(衬衫,衬衫,尺寸(),sx,sy,内部线性);
imwrite(“shirt.png”,shirt);
//翻译发生了
//tx=身体_点.rshx-(sx*衣服_点.rshx);
tx=身体点.rshx-(衣服点.rshx);
ty=身体_点.rshy-(sy*衣服_点.rshy);
//在另一个图像上画一个图像
//src.copyTo(dst.rowRange(1,6).colRange(3,10));
//shirt.copyTo(body.rowRange(tx,shirt.rows).colRange(ty,shirt.cols));
//衬衫.copyTo(body.rowRange(1001000).colRange(100500));
//CVT颜色(衬衫,衬衫,CV_BGRA2BGR);
//CVT颜色(车身,车身,CV_BGRA2BGR);
姓名(以下简称“机构”);
//矩形roi(cv::点(tx,ty),大小(shirt.Size());
//编辑2:Rect.x=0
Rect roi=Rect(0,ty,shirt.cols,shirt.rows);
Mat destinationROI=主体(roi);
//CVT颜色(目的投资回报率、目的投资回报率、CV_BGRA2BGR);
//编辑3:创建遮罩(仅用于显示,需要改进)
垫罩;
CVT颜色(衬衫、面具、灰色);
面罩=面罩<250;
衬衫。复制到(目标ROI,面具);
imwrite(“destinationROI.png”,destinationROI);
imshow(“body”,body);
imwrite(“body.png”,body);
waitKey();
返回0;
}

您的代码太初始。而且你的图像也不适合完美的结果。我猜你对图像执行了真代码,你会得到一个穿着衬衫的人的图像

Mat4b src= imread("path");// to load 4 channel image : imread("path",IMREAD_UNCHANGED); 
Mat3b dest = imread("path");
Rect roi = Rect(179,539,src.cols,src.rows); //src.cols = 1186 and src.rows= 1134 after scaling.
Mat destinationROI = dest(roi);
src.copyTo(destinationROI);
imwrite("destinationROI.png", destinationROI);

我可以写一个代码来获得下面的图像(它是经过Photoshop处理的,只是为了显示结果),但它对你们的图像来说毫无意义

编辑1:

我在这里编辑了你的代码。查看//编辑代码中的1,2,3

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>

using namespace cv;
using namespace std;

float sx, sy;
int tx, ty;

struct TaggingPoint{
int rshx, rshy;
int lshx, lshy;
int topx, topy;
int botx, boty;
}body_points, garment_points;

int main(int argc, char** argv)
{

Mat shirt;
Mat body;

shirt = imread(argv[1], IMREAD_COLOR);
if (shirt.empty())
return -1;

body = imread(argv[2], IMREAD_COLOR);
if (body.empty())
return -1;

body_points.rshx = 418;
body_points.rshy = 706;
body_points.lshx = 1234;
body_points.lshy = 706;
body_points.topx = 838;
body_points.topy = 510;
body_points.botx = 838;
body_points.boty = 1534;

garment_points.rshx = 239;
garment_points.rshy = 147;
garment_points.lshx = 755;
garment_points.lshy = 147;
garment_points.topx = 505;
garment_points.topy = 50;
garment_points.botx = 505;
garment_points.boty = 953;


// edit 1 : when you calculate by this values your shirt image's width will be greater that body image's width
// so to reduce it
sx = (float)(body_points.lshx - body_points.rshx) / (garment_points.lshx - garment_points.rshx)*0.995;
sy = (float)(body_points.boty - body_points.topy) / (garment_points.boty - garment_points.topy);

//scale the image
resize(shirt, shirt, Size(), sx, sy, INTER_LINEAR);

imwrite("shirt.png", shirt);

//translation happened
//  tx = body_points.rshx - (sx * garment_points.rshx);
tx = body_points.rshx - (garment_points.rshx);
ty = body_points.rshy - (sy * garment_points.rshy);

//draw one image over another image
//src.copyTo(dst.rowRange(1, 6).colRange(3, 10));
//  shirt.copyTo(body.rowRange(tx, shirt.rows).colRange(ty, shirt.cols));
//  shirt.copyTo(body.rowRange(100, 1000).colRange(100, 500));

//  cvtColor(shirt, shirt, CV_BGRA2BGR);
//  cvtColor(body, body, CV_BGRA2BGR);


namedWindow("body");
//Rect roi(cv::Point(tx, ty), Size(shirt.size()));

// Edit 2 : Rect.x = 0

Rect roi = Rect(0,ty,shirt.cols,shirt.rows);
Mat destinationROI = body(roi);
//  cvtColor(destinationROI, destinationROI, CV_BGRA2BGR);

// Edit 3 : Create a mask ( it is show purpose only, need improvement )
Mat mask;
cvtColor( shirt, mask, COLOR_BGR2GRAY );
mask = mask < 250;

shirt.copyTo(destinationROI,mask);

imwrite("destinationROI.png", destinationROI);

imshow("body", body);
imwrite("body.png", body);

waitKey();
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
浮子sx,sy;
int-tx,ty;
结构标记点{
int rshx,rshy;
int lshx,lshy;
int-topx,topy;
int-botx,boty;
}身体_点、服装_点;
int main(int argc,字符**argv)
{
垫子衬衫;
垫体;
衬衫=imread(argv[1],imread\u颜色);
if(shirt.empty())
返回-1;
body=imread(argv[2],imread\u颜色);
if(body.empty())
返回-1;
体_点rshx=418;
体_点rshy=706;
体_点lshx=1234;
体_点。lshy=706;
body_points.topx=838;
主体_点。topy=510;
body_points.botx=838;
body_points.boty=1534;
garment_points.rshx=239;
garment_points.rshy=147;
garment_points.lshx=755;
garment_points.lshy=147;
garment_points.topx=505;
garment_points.topy=50;
garment_points.botx=505;
garment_points.boty=953;
//编辑1:通过此值计算时,衬衫图像的宽度将大于身体图像的宽度
//所以要减少它
sx=(浮动)(阀体)