【问题标题】:How to improve sorting pixels in cvMat?如何改进 cvMat 中的像素排序?
【发布时间】:2012-06-23 04:06:05
【问题描述】:

我正在尝试将图像的像素值(例如 80x20)从最低到最高排序。

下面是部分代码:

bool sortPixel(int first, int second)
{
    return (first < second);
}

    vector<int>vect_sortPixel;
    for(int y=0; y<height; y++)
    {
        for(int x=0; x<width; x++)
        {
            vect_sortPixel.push_back(cvGetReal2D(srcImg, y, x));
            sort(vect_sortPixel.begin(), vect_sortPixel.end(), sortPixel);
        }
    }

但是计算需要相当长的时间。有什么减少处理时间的建议吗? 谢谢。

【问题讨论】:

  • 您可以为sort() 方法添加代码吗?
  • 对不起。排序是从(algorithm.h)调用的
  • 在OpenCV中使用sort函数怎么样? docs.opencv.org/modules/core/doc/…
  • 但它声明“如果您想按字典顺序对矩阵行或列进行排序,您可以使用带有适当比较谓词的 STL std::sort 泛型函数。”

标签: c++ sorting opencv


【解决方案1】:

不要使用 getReal2D。这很慢。

将图像转换为 cv::Mat 或 Mat。使用它的数据指针来获取像素值。 Mat.data() 将为您提供指向原始矩阵的指针。用那个。

就排序而言,我建议你先制作一个包含所有像素的数组,然后使用合并排序对其进行排序(时间复杂度 O(n log n))

#include<opencv2/highgui/highgui.hpp>
#include<stdio.h>
using namespace cv;
using namespace std;
int main()
{
    Mat img = imread("filename.jpg",CV_LOAD_IMAGE_COLOR);
    unsigned char *input = (unsigned char*)(img.data);
    int i,j,r,g,b;
    for(int i = 0;i < img.cols;i++){
            for(int j = 0;j < img.rows;j++){
                b = input[img.cols * j + i] ;
                g = input[img.cols * j+ i + 1];
                r = input[img.cols *j + i +2];
            }
        }
    return 0;
}

使用它,您可以访问主矩阵中的像素值。

警告:这不是你比较它的方式。我建议通过使用类似的东西,您可以访问像素值。

Mat.data() 为您提供指向原始矩阵的指针。该矩阵是具有所有给定像素值的一维矩阵。

图像 => (x,y,z),(x1,y1,z1) 等..

Mat(原始矩阵) => x,y,z,x1,y1,z1,...

如果您对如何从 Mat 中提取数据仍有疑问,请访问此链接OpenCV get pixel channel value from Mat image

这是一个关于合并排序的链接http://www.cplusplus.happycodings.com/Algorithms/code17.html

【讨论】:

  • 我该怎么做?能给我举个例子吗?
  • @Mizuki Wikipedia's Merge Sort 文章有一些伪代码。我个人会使用 Radix 或 Quick 排序,因为它们通常更快,尽管它们的代码更复杂。除非您的图像真的很大,否则合并排序应该没问题。
  • 在哪里可以找到 Radiz 或快速排序?是可用的么?感谢您的信息。很有帮助。
  • @MizukiKai 在 STL 中有 qsort。只是谷歌它。我已经告诉过你sort 应该工作得很快。你完成了我告诉你的所有步骤吗?我 100% 确信,这样做后你的算法会非常快。
  • 那你为什么修改你的信息?编辑前:Use its data pointer to get the pixel values. Mat.data() will give you pointer to the original matrix. Use that.这不是建议吗???
【解决方案2】:

您的代码中存在一些问题:

  • 正如Froyo 已经说过你使用cvGetReal2D 这实际上不是很快。您必须将您的cvMat 转换为cv::Mat。要做到这一点,有cv::Mat constructor
// converts old-style CvMat to the new matrix; the data is not copied by default
Mat(const CvMat* m, bool copyData=false);

然后使用this SO question 中提到的直接像素访问。

  • 另一个问题是您使用push_back 实际上也不是很快。你知道数组的大小,为什么不在开始时分配所需的内存呢?像这样:

vector&lt;int&gt; vect_sortPixel(mat.cols*mat.rows);

而不仅仅是使用vect_sortPixel[i] 来获取所需的像素。

  • 为什么在循环中调用sort?当数组已经创建时,您必须在循环之后调用它!默认STL's sort 应该可以快速运行:

复杂性

平均大约 N*logN 次比较(其中 N 是 最后优先)。在最坏的情况下,最多 N^2,具体取决于具体情况 库实现使用的排序算法。

【讨论】:

  • 感谢您的信息。我有点知道下一步该做什么了。它有帮助。
  • 如何仅使用 vect_sortPixel[i] 获取像素?我得先推回去吧?
  • @MizukiKai 不!我已经告诉过你push_back 运行缓慢。如果您知道数组的大小,那么在向量构造函数中分配所需的内存是有意义的。你知道allocateconstructor 是什么意思吗?如果没有,请阅读this article
猜你喜欢
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 1970-01-01
  • 2019-04-22
相关资源
最近更新 更多