как работает copyTo в opencv c ++? - PullRequest
1 голос
/ 27 марта 2020

Я просмотрел приведенный ниже фрагмент и мне было интересно, как работает функция copyTo() in opencv.

 // Make a copy
 Mat faceWithGlassesNaive1 = faceImage.clone();
 // Take the eye region from the image
 Mat roiFace =  faceWithGlassesNaive1(Range(150,250),Range(140,440));
 // Replace the eye region with the sunglass image
 glassBGR.copyTo(roiFace);

Работает ли copyTo() на copyByreference, так что любые изменения, сделанные в roiface, отражаются в faceWithGlassesNaive1? Или я что-то упустил? Нужна помощь.

  1. Ниже изображение лица

faceimage

Ниже изображено стеклоBGR enter image description here

Ниже приведен вывод glassBGR.copyTo(roiFace) из приведенного выше фрагмента enter image description here

Ответы [ 2 ]

1 голос
/ 27 марта 2020

Из документов :

Копирует матрицу в другую.

Метод копирует данные матрицы в другую матрицу. Перед копированием данных метод вызывает:

m.create(this->size(), this->type());

, чтобы при необходимости перераспределить матрицу назначения. В то время как m.copyTo (м); работает безупречно, функция не обрабатывает случай частичного перекрытия между матрицей источника и назначения.

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

Mat glassGray;
cvtColor(glassBGR, glassGray, COLOR_BGR2GRAY);
glassBGR.copyTo(roiFace, glassGray != 255);

Ваша настоящая проблема в том, что roiFace просто псевдоним памяти faceWithGlassesNaive1. Таким образом, изменения, примененные к roiFace (например, копирование в него новых данных), отразятся на faceWithGlassesNaive1. copyTo это не ваша проблема в этом случае, но создание roiFace.

From Mat :: operator () () :

[...] Подобно всему вышеописанному, операторы являются операциями O (1), то есть данные матрицы не копируются.

1 голос
/ 27 марта 2020

copyTo функция opencv как документация говорит:

Метод копирует данные матрицы в другую матрицу.

Итак, вы не может, кроме этого, чтобы выполнить вашу задачу, как это, но вы можете просто достичь ее с помощью такого подхода:

Код:

#include <iostream>    
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

int main()
{

    Mat faceImage = imread("/ur/face/image/directory/elon.jpg");
    Mat glassBGR = imread("/ur/glass/image/directory/glass.png");

    resize(glassBGR,glassBGR,Size(300,100));
    // check each pixel of glass and if its white(255,255,255) then change it with face image pixels
    for(int i=0;i<glassBGR.cols;i++)
    {
        for(int j=0;j<glassBGR.rows;j++)
        {
            if(!(glassBGR.at<Vec3b>(j, i) == Vec3b(255,255,255)))
            {
                faceImage.at<Vec3b>(j+150,i+140) = glassBGR.at<Vec3b>(j, i);
            }
        }
    }

    imshow("result",faceImage);
    waitKey(0);        
}

Результат:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...