Применить маску к изображению в 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");

}
Другие вопросы по тегам