Copy an cv::Mat inside a ROI of another one
OpenCV 2.4:
src.copyTo(dst(Rect(left, top, src.cols, src.rows)));
OpenCV 2.x:
Mat dst_roi = dst(Rect(left, top, src.cols, src.rows));
src.copyTo(dst_roi);
Need to copy one image to another image ROI
This is to confirm that @ypnos educated guess was right (nice call, btw).
Take a look at this code, that performs the same operations as yours:
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat4b m4b(50, 50, Vec4b(0, 255, 0, 255)); // blue image, 4 channels
Mat3b m3b(100, 100, Vec3b(255, 0, 0)); // green image, 3 channels
cout << "After init:" << endl;
cout << "m4b channels: " << m4b.channels() << endl;
cout << "m3b channels: " << m3b.channels() << endl << endl;
Rect roi(0, 0, 50, 50); // roi
// Create a new header for the data inside the roi in m3b
// No data copied, just a new header.
// So destRoi has same number of channels of m3b
Mat destRoi = m3b(roi);
cout << "After roi:" << endl;
cout << "m4b channels : " << m4b.channels() << endl;
cout << "m3b channels : " << m3b.channels() << endl;
cout << "destRoi channels: " << destRoi.channels() << endl << endl;
// destination type != source type
// destRoi is newly created with the destination type
// destRoi doesn't point anymore to the data in m3b and has 4 channels now
m4b.copyTo(destRoi);
cout << "After copyTo:" << endl;
cout << "m4b channels : " << m4b.channels() << endl;
cout << "m3b channels : " << m3b.channels() << endl;
cout << "destRoi channels: " << destRoi.channels() << endl << endl;
return 0;
}
Output:
After init:
m4b channels: 4
m3b channels: 3
After roi:
m4b channels : 4
m3b channels : 3
destRoi channels: 3
After copyTo:
m4b channels : 4
m3b channels : 3
destRoi channels: 4
Solution
Use both matrices with same number of channels, either by:
Load both images as 3 channels matrices
CV_8UC3
. In fact the images you posted are both 3 channelsuse
cvtColor
to convert to the same number of channels, before performing roi and copy operations.
How to copy a rectangular area of a Mat a new Mat of the same size?
create a new image and copy the subimage to roi
cv:: Mat img = cv::imread(...);
cv::Rect roi(x,y,w,h);
cv::Mat subimage= img(roi); // embedded
cv::Mat subimageCopied = subimage.clone(); // copied
cv::Mat newImage=cv::Mat::zeros(img.size(), img.type);
img(roi).copyTo(newImage(roi)); // this line is what you want.
If you have access to the original image, but are not allowed to use its siute information, you can use .copyTo with a mask, but then you have to use the size information to create the mask...
Add a cv::Mat inside a cv::Mat at a specific position
Thanks you @Christoph Rackwitz, with your link I have found the solution.
I convert the python code of Try2Code ( enter link description here )
The final code is here :
void RenderImage::overlayImage(cv::Mat& back, const cv::Mat& front, std::size_t posX, std::size_t posY) {
cv::Mat gray, mask, mask_inv, back_bg, front_bg, result;
cv::Size fsize { front.size() };
cv::cvtColor(front, gray, cv::COLOR_BGR2GRAY);
cv::threshold(gray, mask, 0, 255, cv::THRESH_BINARY);
cv::bitwise_not(mask, mask_inv);
cv::Mat roi { back(cv::Range(posX, posX + fsize.width), cv::Range(posY, fsize.height)) };
cv::bitwise_and(roi, roi, back_bg, mask_inv);
cv::bitwise_and(front, front, front_bg, mask);
cv::add(back_bg, front_bg, result);
cv::addWeighted(roi, 0.1, result, 0.9, 0.0, result);
result.copyTo(back(cv::Rect(posX, posY, fsize.width, fsize.height)));
}
cv::Mat RenderImage::getImage() {
cv::Mat chess = backgroundChess.clone();
overlayImage(chess, piecesChess[0], 128, 0); //The method to merge two images
cv::imshow("Display Image", chess);
cv::waitKey(0);
return chess;
}
Related Topics
Prevent User Process from Being Killed with "End Process" from Process Explorer
Connected Components in Opencv
Tackling Class Imbalance: Scaling Contribution to Loss and Sgd
Is Left and Right Shifting Negative Integers Defined Behavior
Copy Constructor of Template Class
What Is the Optimal Algorithm for Generating an Unbiased Random Integer Within a Range
Why Is Sizeof(Std::String) Only Eight Bytes
C++ Templates, Undefined Reference
Does Moving Leave the Object in a Usable State
Changing the Value of Const Variable in C++
Linux Equivalent for Conio.H Getch()
Unsequenced Value Computations (A.K.A Sequence Points)
Why Don't the C or C++ Standards Explicitly Define Char as Signed or Unsigned
What Is the Precision of Long Double in C++
Repeated Multiple Definition Errors from Including Same Header in Multiple Cpps
Overload Handling of Std::Endl
Is the Backslash Acceptable in C and C++ #Include Directives