it-swarm.com.ru

Применить маску к изображению в OpenCV?

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

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

Благодарю вас

16
fdh

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

8
SSteve

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

inputMat.copyTo(outputMat, maskMat);

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

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

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

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

54
Chaos_99

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

cvCopy(origImage,destImage,mask);

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

Смотрите больше в документы OpenCV

5
volpato

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

Вот некоторый код для применения бинарной маски к последовательности видеокадров, полученной с веб-камеры . Комментарий и раскомментируйте строку «bitwise_not (Mon_mask, Mon_mask);» и посмотрите эффект.

bests, Ahmed.

#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");

}
0
Ahmed