В Matlab, если A - матрица, sum (A) обрабатывает столбцы A как векторы, возвращая вектор строки из сумм каждого столбца.
sum (изображение); Как это можно сделать с помощью OpenCV?
В Matlab, если A - матрица, sum (A) обрабатывает столбцы A как векторы, возвращая вектор строки из сумм каждого столбца.
sum (изображение); Как это можно сделать с помощью OpenCV?
Для 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
Использование 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.
cvSum учитывает ROI, поэтому, если вы перемещаете окно шириной 1 px по всему изображению, вы можете рассчитать сумму каждого столбца.
Мой С++ получил немного ржавый, поэтому я не буду приводить пример кода, хотя в последний раз, когда я это делал, я использовал OpenCVSharp, и он работал нормально. Однако я не уверен, насколько эффективен этот метод.
Мои математические навыки тоже становятся ржавыми, но не следует ли суммировать все элементы в столбцах в матрице, умножая их на вектор 1s?
Я использовал метод 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);
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);