Opencv: как создать новую матрицу из существующей матрицы с некоторыми изменениями?

в OpenCV у меня есть такая матрица: [3 4 2; 5 2 1; 6 7 9], то есть размером 3х3. Теперь я хочу изменить его на размер 3x1 и сделать так: [3 4 2 5 2 1 6 7 9]. Но это не совсем то, что я хочу, моя актуальная цель — ставить ноль до и после каждого значения, при этом повторять каждое значение трижды. Итак, моя матрица целей должна быть такой: [ 0 3 3 3 0 0 4 4 4 0 0 2 2 2 0 0 5 5 5 0 0 2 2 2 0 0 1 1 1 0 0 6 6 6 0 0 7 7 7 0 0 9 9 9 0]. Я написал для этого следующий код:

for ( int i = 0; i < 3; i ++ )
    {
        for ( int j = 0; j < 3; j ++ )
        {               
                for ( int m = k + 1; m < m + 3; m ++ )
                {
                    dstMat.col (m) = srcMat.at <int> ( i, j );

                }

                k = k + 5 ;                 
        }
    }

Есть ли лучший способ сделать это? Особенно без цикла for это действительно сбивает с толку. Спасибо заранее.


person E_learner    schedule 09.08.2012    source источник


Ответы (2)


Вы можете использовать Mat::reshape, чтобы преобразовать матрицу 3x3 в 3x1. Таким образом, вам понадобится один цикл for вместо двух, и это операция O(1).

вы можете пропустить следующий цикл for, используя ROI:

  srcMat.reshape(0,1);
  for (int i =0; i < 9; i++)
    dstMat(cv::Range::all(), cv::Range(i*5+1, i*5+4)).setTo(srcMat.at<int>(i));

и это было бы все.

person Mohammad    schedule 09.08.2012
comment
Большое спасибо за ответ. Строка srcMat.reshape(0,1) не работает, но если я изменю ее на srcMat.reshape(1,0), она будет работать. Но это отличается от того, что я хочу. Знаете, в чем может быть причина? Я читаю видеокадр здесь как srcMat. - person E_learner; 10.08.2012
comment
Первый параметр — это количество каналов в новой матрице, а второй параметр — это количество строк. когда вы указываете ноль для второго параметра, вы все еще застряли с матом 3x3. проблема может быть в чем-то другом, вы уверены, что исходная матрица имеет тип int? - person Mohammad; 10.08.2012
comment
Исходная матрица имеет тип CV_8U. Любые идеи? Спасибо еще раз. - person E_learner; 10.08.2012
comment
для CV_8U использовать srcMat.at<unsigned char>(i) - person Mohammad; 10.08.2012
comment
Еще раз спасибо за ваш ответ. Я изменился, как ты сказал. Но я обнаружил, что проблема в строке srcMat.reshape(0,1). В настоящее время я использую srcMat размером 800x600. Любое предложение? - person E_learner; 13.08.2012
comment
Уважаемый Мохаммад, часть изменения формы теперь в порядке, но проблема в цикле for. Мой приведенный dstMat - это все нули. Мой srcMat не является нулевой матрицей. Есть ли у вас какие-либо идеи? Спасибо. - person E_learner; 13.08.2012
comment
Я только что обнаружил, что результирующий dstMat отличен от нуля только в цикле for, но снаружи он вообще равен нулю. Есть идеи? Заранее спасибо. - person E_learner; 13.08.2012
comment
cv::Mat предыдущий кадр (800, 600, CV_8UC3, предыдущий кадр); cv::Mat захваченный кадр (800, 600, CV_8UC3, currentFrame); cv::Mat subtractedFrame = вычесть (предыдущий кадр, захваченный кадр); cv::Mat medianMat; cv::Mat dstMat; cv::medianBlur (subtractedFrame, medianMat, 5 ); cv::Mat reShapedMedianMat = medianMat.reshape ( 0, 1 ); for (int i = 0; i ‹ resizedMedianMat.cols; i ++) { dstMat (cv::Range::all(), cv::Range (i * 5 + 1, i * 5 + 4)).setTo ( изменено MedianMat.at ‹int›(i)); } - person E_learner; 14.08.2012

Вы можете начать с вызова reshape для вашей матрицы, чтобы сгладить ее до одной строки/столбца. . Это избавит вас от одного из циклов for и сделает его немного понятнее.

person Hammer    schedule 09.08.2012