Как заменить значения в мате, используя другое изображение мата - PullRequest
0 голосов
/ 04 декабря 2018

У меня мат Matx 480x480 и Mat B. 478x478. Я хочу заполнить Mat A (исключая границы A), используя Mat B в C ++.В python я использую следующие обозначения от numpy

A[1:-1,1:-1] = B[:,:,0]

Чтобы добиться того же в c ++, я попытался использовать следующий код с использованием каналов и диапазона, но он не работал.

std::vector<Mat> B_channel(3);
split(B, B_channel);
A(cv::Range(1,479), cv::Range(1, 479)) = B_channel[0];

Как добиться того же в C ++.

1 Ответ

0 голосов
/ 04 декабря 2018

Для того же эффекта вашего кода Python в C ++ вы можете сделать что-то вроде следующего примера:

  cv::Mat A(100, 100, CV_8U, cv::Scalar::all(0));
  cv::Mat B(98, 98, CV_8U, cv::Scalar::all(1));
  std::cout << "sumAll A: " << cv::sum(A) << std::endl;

  B.copyTo(A.colRange(1, A.cols - 1).rowRange(1, A.rows - 1)); // This is the copy part
  std::cout << "sumAll A: " << cv::sum(A) << std::endl;

Я печатаю сумму всех, чтобы убедиться, что она скопировала его.Первый случай дал 0, а второй - 9604. Что верно в обоих случаях.Важно помнить: если несоответствие размера, copyTo переинициализирует матрицу и может дать неожиданные результаты.

Чтобы разбить код немного больше, это:

A.colRange(1, A.cols - 1).rowRange(1, A.rows - 1)

эквивалентно:

 A[1:-1,1:-1]

в Python, а copyTo скопирует значения(а не заголовок) из одного cv :: Mat в другой.Если вы используете оператор копирования (=), он будет копировать только заголовки, и в этом случае он просто записывает его во временный заголовок, который вы создали с помощью A(cv::Range(1,479), cv::Range(1, 479)), что больше для доступа к данным внутри A. После инструкции этот заголовокуничтожается и ваши данные точно такие же.

Чтобы получить часть заголовка, в которую вы хотите скопировать, вы можете сделать это несколькими способами.Я написал ряд столбцов и строк.Другой - тот, который вы написали (с двумя диапазонами), а третий использует cv::Rect.Таким образом, в конце все это эквивалентно:

B.copyTo(A.colRange(1, A.cols - 1).rowRange(1, A.rows - 1));
B.copyTo(A(cv::Range(1, A.cols - 1), cv::Range(1, A.rows - 1)));
B.copyTo(A(cv::Rect(1,1,A.cols -2, A.rows -2)));

В последнем случае cv :: Rect равно (x, y, width, height), следовательно, -2 вместо -1 других случаев.

И вы можете сделать то же самое для B перед использованием copyTo, чтобы получить подмножество изображения B.

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