[英]opencv how to visualize a non-rectangular region (roi) in a performant way
我有一個圖像(cv :: Mat)和一個可被視為蒙版的ROI。 我想顯示原始圖像,並在上面混合了ROI。
我的蒙版比我的原始圖像小:每個元素代表圖像中的一塊。 假設我的面具是這個(請注意我的面具不是矩形)
0 0 1
1 1 1
0 0 0
那么我想讓(mask == 1)的部分保持不變,其余部分與顏色混合。 這是我的代碼
cv::Mat blocks = image.clone;
uint npixcol = 32;
uint npixrow = 32;
for (uint ri = 0; ri < 480; ++ri)
for (uint ci = 0; ci < 640; ++ci)
{
if (mask[ri * 640 + ci])
cv::rectangle(blocks, cv::Rect(ci * npixcol, ri * npixrow, npixcol, npixrow), cv::Scalar(0, 0, 0), CV_FILLED, 8, 0);
}
cv::addWeighted(image, 0.5, blocks, 0.5, 0, image, -1);
如果沒有額外的“ clone”命令,我該怎么辦呢?
使其更清楚; 這是我想要的示例(顏色並不重要)!
您的口罩顏色不變嗎? 假設遮罩與圖像的尺寸相同(您可以輕松縮放):
//Manually instead of addWeighted()
for (uint ri = 0; ri < 480; ++ri)
for (uint ci = 0; ci < 640; ++ci)
{
if (mask[ri * 640 + ci])
{
image.at<uchar>(ri,ci) [0] = image.at<uchar>(ri,ci) [0] * weight_blue;
image.at<uchar>(ri,ci) [1] = image.at<uchar>(ri,ci) [1] * weight_green;
image.at<uchar>(ri,ci) [2] = image.at<uchar>(ri,ci) [2] * weight_red;
}
}
根據您的評論,如果可以制作與原始圖像尺寸相同的蒙版,則可以使用迭代器直接修改原始圖像像素值。 這是一個獨立的示例:
#include <cstdlib>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
int
main(int argc, char *argv[])
{
cv::Mat image = cv::imread(argv[1]);
cv::Mat mask = cv::Mat::zeros(image.size(), CV_8U);
// let's put some 1 in my test mask.
cv::Mat roi = mask(cv::Rect(0,0,mask.cols/2, mask.rows/2));
roi = 1;
cv::Vec3b blue(255,0,0); // (B,G,R)
float alpha = 0.5;
// Let's have fun with iterators
cv::MatConstIterator_<unsigned char> maskIter = mask.begin<unsigned char>();
const cv::MatConstIterator_<unsigned char> maskIterEnd = mask.end<unsigned char>();
cv::MatIterator_<cv::Vec3b> imageIter = image.begin<cv::Vec3b>();
for (; maskIter != maskIterEnd; ++maskIter, ++imageIter) {
if (*maskIter) {// mask == 1
*imageIter = (1-alpha)*(*imageIter) + alpha*blue; // same as addWeighted
}
}
cv::namedWindow("image", 0);
cv::imshow("image", image);
cv::waitKey(0);
return EXIT_SUCCESS;
}
基本上,您想檢查一下自己是否在roi內。 然后,它應該返回一個指向原始圖像的指針。 如果您不在室內,則希望具有某種顏色。
您可以使用自己的Mat包裝器來做到這一點。
MyMat::at(int x, int y){
if(inRoi(x,y)){
return original.at(x,y);
else
return color(0,0,0);
}
我認為您不能將一個圖像的subImage指向另一個圖像。 (這意味着我認為您無法將藍色圖像中的像素重定向到原始圖像上)
Mat blueImage;
Rect roi;
Mat roiInImage = blueImage(roi);
roiInImage.redirect = originalImage(roi); //don't think something like this is possible
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.