Сумма каждого столбца opencv - PullRequest
       5

Сумма каждого столбца opencv

11 голосов
/ 24 февраля 2011

В Matlab, если A - матрица, sum (A) обрабатывает столбцы A как векторы, возвращая вектор-строку сумм каждого столбца.

сумма (изображение); Как это можно сделать с помощью OpenCV?

Ответы [ 4 ]

32 голосов
/ 05 ноября 2011

Использование cvReduce сработало для меня.Например, если вам нужно сохранить сумму столбцов матрицы в виде матрицы строк, вы можете сделать это:

CvMat * MyMat = cvCreateMat(height, width, CV_64FC1);
// Fill in MyMat with some data...

CvMat * ColSum = cvCreateMat(1, MyMat->width, CV_64FC1);
cvReduce(MyMat, ColSum, 0, CV_REDUCE_SUM);

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

3 голосов
/ 02 апреля 2015

РЕДАКТИРОВАТЬ через 3 года:

Правильная функция для этого: cv :: redu .

Уменьшает матрицу до вектора.

Функция Reduce уменьшает матрицу до вектора, обрабатывая строки / столбцы матрицы в виде набора одномерных векторов и выполнения указанная операция над векторами, пока одна строка / столбец не будет получен. Например, функция может использоваться для вычисления горизонтального и вертикальные проекции растрового изображения. В случае REDUCE_MAX и REDUCE_MIN, выходное изображение должно иметь тот же тип, что и источник один. В случае REDUCE_SUM и REDUCE_AVG выход может иметь большая битовая глубина элемента для сохранения точности. И многоканальный массивы также поддерживаются в этих двух режимах сокращения.

OLD : Я использовал метод ROI: переместите ROI высоты изображения и ширины 1 слева направо и рассчитайте среднее значение.

 Mat src = imread(filename, 0);     
 vector<int> graph( src.cols );
 for (int c=0; c<src.cols-1; c++)
 {
     Mat roi = src( Rect( c,0,1,src.rows ) );
     graph[c] = int(mean(roi)[0]);
 }

 Mat mgraph(  260, src.cols+10, CV_8UC3); 
 for (int c=0; c<src.cols-1; c++)
 {
     line( mgraph, Point(c+5,0), Point(c+5,graph[c]), Scalar(255,0,0), 1, CV_AA);    
 }

 imshow("mgraph", mgraph);
 imshow("source", src);

BLOT-stripe Intensity graph

EDIT: Просто из любопытства я попытался изменить размер до высоты 1, и результат был почти таким же:

 Mat test;
 cv::resize(src,test,Size( src.cols,1 ));
 Mat mgraph1(  260, src.cols+10, CV_8UC3); 
 for(int c=0; c<test.cols; c++) 
 {
        graph[c] = test.at<uchar>(0,c);
 }
 for (int c=0; c<src.cols-1; c++)
 {
     line( mgraph1, Point(c+5,0), Point(c+5,graph[c]), Scalar(255,255,0), 1, CV_AA);     
 }
 imshow("mgraph1", mgraph1);

Cols mean graph by resizing to height 1

2 голосов
/ 06 июля 2014

cvSum учитывает рентабельность инвестиций, поэтому, если вы переместите окно шириной 1 пиксель по всему изображению, вы можете рассчитать сумму для каждого столбца.

Мой c ++ стал немного ржавым, поэтому я не буду приводить пример кода, хотя в последний раз, когда я делал это, я использовал OpenCVSharp, и он работал нормально. Однако я не уверен, насколько эффективен этот метод.

Мои математические навыки тоже устарели, но неужели нельзя суммировать все элементы в столбцах матрицы, умножив их на вектор 1 с?

0 голосов
/ 24 февраля 2011

Для 8-битного изображения в оттенках серого должно работать следующее (я думаю).Это не должно быть слишком сложно для расширения до различных типов изображений.

int imgStep = image->widthStep;
uchar* imageData = (uchar*)image->imageData;
uint result[image->width];
memset(result, 0, sizeof(uchar) * image->width);
for (int col = 0; col < image->width; col++) {
  for (int row = 0; row < image->height; row++) {
    result[col] += imageData[row * imgStep + col];
  }
}

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