#c #opencv #opencv4
#c #opencv
Вопрос:
Я хочу поменять местами две строки в Mat M
, и у меня есть две незначительные проблемы:
- Чтобы поменять местами две строки, мне понадобится
MatrixRow temp
(псевдокод) для резервного копирования первой строки, подлежащей замене. Но я не знаю, каким должен быть тип строки aMat
.
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 я бы рекомендовал вам использовать следующие шаги:
- Создайте временный mat размером 1 строка x n столбцов, где n — ширина изображения
- Скопируйте значения пикселей из i-й строки во временный mat с помощью цикла for
- Скопируйте значения пикселей из j-й строки в i-ю строку, используя ту же технику цикла for
- Скопируйте значения пикселей из временного mat в j-ю строку
Это решение, основанное на том, что я понял из предоставленной информации.
Комментарии:
1. Но мне нужен код, извините, на самом деле это не помогает… Все равно спасибо за ваше время.