在特定位置的 cv::Mat 内添加 cv::Mat
Add a cv::Mat inside a cv::Mat at a specific position
我目前正在制作一个渲染国际象棋游戏的软件。为此,我使用 OpenCV。
这个想法是将棋盘放在 cv::Mat 中,并添加 std::array 为 cv::Mat 的棋子:
RenderImage::RenderImage() {
backgroundChess = cv::imread("files/board_chess4.png"); /// The chess board
piecesChess[0] = cv::imread("files/pieces/wP.png"); /// The pieces
piecesChess[1] = cv::imread("files/pieces/wB.png");
piecesChess[2] = cv::imread("files/pieces/wN.png");
piecesChess[3] = cv::imread("files/pieces/wR.png");
piecesChess[4] = cv::imread("files/pieces/wQ.png");
piecesChess[5] = cv::imread("files/pieces/wK.png");
piecesChess[6] = cv::imread("files/pieces/bP.png");
piecesChess[7] = cv::imread("files/pieces/bB.png");
piecesChess[8] = cv::imread("files/pieces/bN.png");
piecesChess[9] = cv::imread("files/pieces/bR.png");
piecesChess[10] = cv::imread("files/pieces/bQ.png");
piecesChess[11] = cv::imread("files/pieces/bK.png");
}
后来,我做了一个尝试在棋盘上加棋子的方法。
我已经开始使用 copyTo:
cv::Mat RenderImage::getImage() {
cv::Mat 国际象棋 = backgroundChess.clone();
piecesChess[0].copyTo(chess(cv::Rect(0,0, piecesChess[0].cols, piecesChess[0].rows)));
cv::imshow("Display Image", chess);
cv::waitKey(0);
return chess;
}
但我的作品周围有一个黑色方块:
所以我尝试了自己的方法:
void RenderImage::merge2img(cv::Mat& back, const cv::Mat front, std::size_t posX, std::size_t posY) {
cv::Size bsize { back.size() };
cv::Size fsize { front.size() };
for (std::size_t startX {posX}; startX < posX + fsize.width && startX < bsize.width; startX++) {
for (std::size_t startY {posY}; startY < posY + fsize.height && startY < bsize.height; startY++) {
cv::Vec4b fpixel { front.at<cv::Vec4b>(startY, startX) };
cv::Vec4b bpixel { back.at<cv::Vec4b>(startY, startX) };
for (int i {0}; i < 3; i++) {
back.at<cv::Vec4b>(startY, startX)[i] = (fpixel[i] * fpixel[3] + bpixel[i] * (255 - fpixel[3])) / 255;
}
back.at<cv::Vec4b>(startY, startX)[3] = 255;
}
}
}
并且我更改了方法 getImage()
cv::Mat RenderImage::getImage() {
cv::Mat chess = backgroundChess.clone();
//addWeighted( piecesChess[0], 0.5, backgroundChess, 0.5, 0.0, chess);
merge2img(chess, piecesChess[0], 0, 0);
//piecesChess[0].copyTo(chess(cv::Rect(0,0, piecesChess[0].cols, piecesChess[0].rows)));
cv::imshow("Display Image", chess);
//cv::imshow("Display Image", piecesChess[0]);
cv::waitKey(0);
return chess;
}
But the result have this problem :
所以你能帮我找到一个在我的棋盘里画棋子的解决方案吗?
谢谢
谢谢你@Christoph Rackwitz,你 link 我找到了解决方案。
我转换 Try2Code ( enter link description here )
的 python 代码
最终代码在这里:
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;
}
我目前正在制作一个渲染国际象棋游戏的软件。为此,我使用 OpenCV。 这个想法是将棋盘放在 cv::Mat 中,并添加 std::array 为 cv::Mat 的棋子:
RenderImage::RenderImage() {
backgroundChess = cv::imread("files/board_chess4.png"); /// The chess board
piecesChess[0] = cv::imread("files/pieces/wP.png"); /// The pieces
piecesChess[1] = cv::imread("files/pieces/wB.png");
piecesChess[2] = cv::imread("files/pieces/wN.png");
piecesChess[3] = cv::imread("files/pieces/wR.png");
piecesChess[4] = cv::imread("files/pieces/wQ.png");
piecesChess[5] = cv::imread("files/pieces/wK.png");
piecesChess[6] = cv::imread("files/pieces/bP.png");
piecesChess[7] = cv::imread("files/pieces/bB.png");
piecesChess[8] = cv::imread("files/pieces/bN.png");
piecesChess[9] = cv::imread("files/pieces/bR.png");
piecesChess[10] = cv::imread("files/pieces/bQ.png");
piecesChess[11] = cv::imread("files/pieces/bK.png");
}
后来,我做了一个尝试在棋盘上加棋子的方法。 我已经开始使用 copyTo:
cv::Mat RenderImage::getImage() { cv::Mat 国际象棋 = backgroundChess.clone();
piecesChess[0].copyTo(chess(cv::Rect(0,0, piecesChess[0].cols, piecesChess[0].rows)));
cv::imshow("Display Image", chess);
cv::waitKey(0);
return chess;
}
但我的作品周围有一个黑色方块:
所以我尝试了自己的方法:
void RenderImage::merge2img(cv::Mat& back, const cv::Mat front, std::size_t posX, std::size_t posY) {
cv::Size bsize { back.size() };
cv::Size fsize { front.size() };
for (std::size_t startX {posX}; startX < posX + fsize.width && startX < bsize.width; startX++) {
for (std::size_t startY {posY}; startY < posY + fsize.height && startY < bsize.height; startY++) {
cv::Vec4b fpixel { front.at<cv::Vec4b>(startY, startX) };
cv::Vec4b bpixel { back.at<cv::Vec4b>(startY, startX) };
for (int i {0}; i < 3; i++) {
back.at<cv::Vec4b>(startY, startX)[i] = (fpixel[i] * fpixel[3] + bpixel[i] * (255 - fpixel[3])) / 255;
}
back.at<cv::Vec4b>(startY, startX)[3] = 255;
}
}
}
并且我更改了方法 getImage()
cv::Mat RenderImage::getImage() {
cv::Mat chess = backgroundChess.clone();
//addWeighted( piecesChess[0], 0.5, backgroundChess, 0.5, 0.0, chess);
merge2img(chess, piecesChess[0], 0, 0);
//piecesChess[0].copyTo(chess(cv::Rect(0,0, piecesChess[0].cols, piecesChess[0].rows)));
cv::imshow("Display Image", chess);
//cv::imshow("Display Image", piecesChess[0]);
cv::waitKey(0);
return chess;
}
But the result have this problem :
所以你能帮我找到一个在我的棋盘里画棋子的解决方案吗? 谢谢
谢谢你@Christoph Rackwitz,你 link 我找到了解决方案。 我转换 Try2Code ( enter link description here )
的 python 代码最终代码在这里:
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;
}