Применить маску к изображению в OpenCV?
У меня есть двоичная маска, которую я хочу навсегда применить к цветному изображению, как бы я это сделал? Двоичная маска должна быть предпочтительно постоянной - так как я не хочу повторно применять маску к изображению каждый раз, когда я вызываю функцию.
Основные примеры кода будут оценены. Если вы используете код, объясните код, а не просто публикуйте его.
Благодарю вас
6 ответов
Вы не применяете бинарную маску к изображению. Вы (необязательно) используете двоичную маску в вызове функции обработки, чтобы сообщить функции, какие пиксели изображения вы хотите обработать. Если я полностью неверно истолковал ваш вопрос, вы должны добавить больше деталей, чтобы уточнить.
Хотя ответ @perrejba верен, он использует устаревшие функции в стиле C. Поскольку вопрос помечен C++, вы можете вместо этого использовать метод:
inputMat.copyTo(outputMat, maskMat);
Все объекты имеют тип cv::Mat
,
Пожалуйста, имейте в виду, что маскирование является двоичным. Любое ненулевое значение в маске интерпретируется как "do copy". Даже если маска представляет собой изображение в градациях серого.
Также имейте в виду, что функция.copyTo() не очищает вывод перед копированием.
Если вы хотите навсегда изменить исходное изображение, вам необходимо выполнить дополнительное копирование / клонирование / назначение. Функция copyTo () не определена для перекрывающихся входных / выходных изображений. Таким образом, вы не можете использовать одно и то же изображение как для ввода, так и для вывода.
Ну, этот вопрос появляется в верхней части результатов поиска, поэтому я считаю, что нам нужен пример кода здесь. Вот код Python:
import cv2
def apply_mask(frame, mask):
"""Apply binary mask to frame, return masked image.
"""
return cv2.bitwise_and(frame, frame, mask=mask)
Маска и рамка должны быть одинакового размера, поэтому пиксели остаются там, где есть маска 1
и установлены в ноль, где пиксель маски 0
,
И для C++
это немного по-другому:
cv::Mat inFrame; // Original (non-empty) image
cv::Mat mask; // Original (non-empty) mask
// ...
cv::Mat outFrame; // Result output
inFrame.copyTo(outFrame, mask);
Вы можете использовать маску для копирования только интересующей области исходного изображения в целевое изображение:
cvCopy(origImage,destImage,mask);
где mask
должен быть 8-битным одноканальным массивом.
Смотрите больше в документации OpenCV
Используйте копию с маской.
Пример кода:
Mat img1 = imread(path); // Load your image
Mat mask(img1 .size(),img1 .type()); // Create your mask
mask.setTo(0);
Point center(img1.cols/2, img1.rows / 2);
const int radius = img1.cols / 5; // Circle radio
circle(mask, center, radius, 255, FILLED);// Draw a circle in the image center
Mat img2(img1 .size(),img1 .type()); // Outimage
img2.setTo(0); // Clear data
img1.copyTo(img2, mask); // Only values at mask > 0 will be copied.
Вот некоторый код для применения двоичной маски к последовательности видеокадров, полученной с веб-камеры. закомментируйте и раскомментируйте строку "bitwise_not(Mon_mask,Mon_mask);" и просмотрите эффект.
лучше, Ахмед.
#include "cv.h" // include it to used Main OpenCV functions.
#include "highgui.h" //include it to use GUI functions.
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
int c;
int radius=100;
CvPoint2D32f center;
//IplImage* color_img;
Mat image, image0,image1;
IplImage *tmp;
CvCapture* cv_cap = cvCaptureFromCAM(0);
while(1) {
tmp = cvQueryFrame(cv_cap); // get frame
// IplImage to Mat
Mat imgMat(tmp);
image =tmp;
center.x = tmp->width/2;
center.y = tmp->height/2;
Mat Mon_mask(image.size(), CV_8UC1, Scalar(0,0,0));
circle(Mon_mask, center, radius, Scalar(255,255,255), -1, 8, 0 ); //-1 means filled
bitwise_not(Mon_mask,Mon_mask);// commenté ou pas = RP ou DMLA
if(tmp != 0)
imshow("Glaucom", image); // show frame
c = cvWaitKey(10); // wait 10 ms or for key stroke
if(c == 27)
break; // if ESC, break and quit
}
/* clean up */
cvReleaseCapture( &cv_cap );
cvDestroyWindow("Glaucom");
}