Применить маску к изображению в OpenCV? - PullRequest
18 голосов
/ 20 сентября 2011

У меня есть двоичная маска, которую я хочу навсегда применить к цветному изображению, как бы я это сделал? Двоичная маска должна быть предпочтительно постоянной - так как я не хочу повторно применять маску к изображению каждый раз, когда я вызываю функцию.

Основные примеры кода приветствуются. Если вы используете код, объясните код, а не просто публикуйте его.

Спасибо

Ответы [ 5 ]

59 голосов
/ 10 августа 2013

Хотя ответ @perrejba верен, он использует устаревшие функции в стиле C. Поскольку вопрос помечен C ++, вы можете вместо этого использовать метод:

inputMat.copyTo(outputMat, maskMat);

Все объекты имеют тип cv::Mat.

Обратите внимание, что маскирование является двоичным. Любое ненулевое значение в маске интерпретируется как «do copy». Даже если маска представляет собой изображение в градациях серого.

Также помните, что функция .copyTo () не очищает вывод перед копированием.

Если вы хотите навсегда изменить исходное изображение, вам необходимо выполнить дополнительное копирование / клонирование / назначение. Функция copyTo () не определена для перекрывающихся входных / выходных изображений. Таким образом, вы не можете использовать одно и то же изображение как для ввода, так и для вывода.

10 голосов
/ 21 сентября 2011

Вы не применяете двоичную маску к изображению.Вы (опционально) используете двоичную маску в вызове функции обработки, чтобы сообщить функции, какие пиксели изображения вы хотите обработать.Если я полностью неверно истолковал ваш вопрос, вы должны добавить больше деталей для уточнения.

5 голосов
/ 27 марта 2013

Вы можете использовать маску для копирования только области интереса исходного изображения в целевое:

cvCopy(origImage,destImage,mask);

, где mask должен быть 8-битным одноканальным массивом.

Подробнее см. В OpenCV документах

2 голосов
/ 10 марта 2018

Ну, этот вопрос появляется в верхней части результатов поиска, поэтому я считаю, что нам нужен пример кода здесь. Вот код 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);
1 голос
/ 06 ноября 2013

Вот некоторый код для применения двоичной маски к последовательности видеокадров, полученной с веб-камеры.закомментируйте и раскомментируйте строку «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");

}
...