Как поменять местами строки Mat в opencv?

#c #opencv #opencv4

#c #opencv

Вопрос:

Я хочу поменять местами две строки в Mat M , и у меня есть две незначительные проблемы:

  1. Чтобы поменять местами две строки, мне понадобится MatrixRow temp (псевдокод) для резервного копирования первой строки, подлежащей замене. Но я не знаю, каким должен быть тип строки a Mat .

 Mat temp = img.row(i).clone();
img.row(i) = img.row(j).clone();
img.row(j) = temp.clone();
  

Этот код не изменяет img, почему?

Комментарии:

1. Что здесь i и j? Находятся ли они в цикле?

2. @YunusTemurlenk: Да.

Ответ №1:

 img.row(i) = img.row(j).clone();
  

и

 img.row(j) = temp.clone();
  

не копируйте клонированные данные, потому что они вызывают следующий оператор присваивания

 Matamp; cv::Mat::operator= (const Matamp; m)  
  

Смотрите документацию

Назначение матрицы — это операция O (1). Это означает, что никакие данные не копируются, но данные являются общими, а счетчик ссылок, если таковой имеется, увеличивается.

Для копирования есть другой оператор присваивания, который вы можете использовать:

 Matamp; cv::Mat::operator= (const MatExpramp; expr)
  

Подробности см. в матричных выражениях.

Итак, вы можете сделать что-то вроде следующего, чтобы фактически скопировать данные.

 img.row(i) = img.row(j).clone()   0;
img.row(j) = temp.clone()   0;
  

И вам не нужен клон. Таким образом, это может быть записано как

 img.row(i) = img.row(j)   0;
img.row(j) = temp   0;
  

Здесь img.row(j) 0 создается матричное выражение, поэтому вы вызываете Matamp; cv::Mat::operator= (const MatExpramp; expr) оператор присваивания в img.row(i) = img.row(j) 0; .

И другой вариант — скопировать данные, как указано в другом ответе. Для этого вы можете использовать Mat::copyTo .

Для получения дополнительной информации см. Примечание в документации для

 Mat cv::Mat::row(int y) const
  

Это объясняется примерами.

Комментарии:

1. Прежде чем вы написали ответ, я действительно обнаружил, что это img.row(j).copyTo(img.row(i)) работает, и я прочитал из их руководства, которое заканчивается так же, как ваша первая цитата: копируется только заголовок. 0 Техника — это новая идея для меня, если вы могли бы подробнее рассказать об этом, я буду признателен за вашу работу. Короче говоря, вы решили мою проблему, спасибо!

2. Я изучаю OpenCV в этом семестре, вы можете следовать моему идентификатору, чтобы ответить на мои проблемы, и я всегда буду голосовать за вас, если все ваши ответы такого высокого качества.

3. @Raining img.row(j) 0 создает матричное выражение, поэтому вы вызываете Matamp; cv::Mat::operator= (const MatExpramp; expr) оператор присваивания в img.row(i) = img.row(j) 0; .

4. Я бы порекомендовал вам обновить свой ответ или (если у меня есть свободное время) Я помогу вам отредактировать ваш ответ, добавив к вашему ответу то, что я считаю полезным для себя.

Ответ №2:

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

  1. Создайте временный mat размером 1 строка x n столбцов, где n — ширина изображения
  2. Скопируйте значения пикселей из i-й строки во временный mat с помощью цикла for
  3. Скопируйте значения пикселей из j-й строки в i-ю строку, используя ту же технику цикла for
  4. Скопируйте значения пикселей из временного mat в j-ю строку

Это решение, основанное на том, что я понял из предоставленной информации.

Комментарии:

1. Но мне нужен код, извините, на самом деле это не помогает… Все равно спасибо за ваше время.