将像素/元素映射到百分位数(C ++ / OpenCV)

时间:2018-06-27 13:22:41

标签: c++ opencv image-processing

我正在使用OpenCV,但我想在图像上解决以下问题。但是,如果有问题的话,我的问题并不仅限于OpenCV,它可以是在向量上更通用的c ++。

问题

我想将输入图像(或输入向量的元素)的像素值映射到相同大小的输出图像(或向量)。输出的每个元素都应包含输入中相应元素的百分比*。

我的问题是

  

我将如何编码此问题的实现? (在c ++或OpenCV中)

示例

为简单起见,我将展示一维图像的示例。

输入: (1, 2, 10, 3, 4, 5, 6, 12, 7)

输出*:(0.11, 0.22, 0.89, 0.33, 0.44, 0.56, 0.67, 1.00, 0.78)

性能?

我正在写代码来分析可能几百乘几百的图像。我假设我的问题可能在O(n log n)中出现,但我认为即使O(n ^ 2)也不会成为问题(其中n是图像/矢量中元素的总数)。但是,如果精确的百分位数导致太多的复杂性问题,那么我可以使用一定数量的垃圾箱。


(*)我知道,无论您向上舍入还是向下舍入,都有几种不同的概念化百分位数。这对我来说并不重要。无论哪种方法。

1 个答案:

答案 0 :(得分:1)

我不确定这不是您要查找的内容,但这是图像像素值的百分位数的幼稚实现。

    cv::Mat image = cv::imread("image.jpg",cv::IMREAD_UNCHANGED);

    // convert image to gray
    cv::Mat gray;
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);

    // calculate histogram for every pixel value (i.e [0 - 255])
    cv::Mat hist;
    int histSize = 256;
    float range[] = { 0, 256 } ;
    const float* histRange = { range };
    bool uniform = true; bool accumulate = false;
    cv::calcHist( &gray, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, uniform, accumulate );

    // total pixels in image
    float totalPixels = gray.cols * gray.rows;

    // calculate percentage of every histogram bin (i.e: pixel value [0 - 255])
    // the 'bins' variable holds pairs of (int pixelValue, float percentage) 
    std::vector<std::pair<int, float>> bins;
    float percentage;
    for(int i = 0; i < 256; ++i)
    {
        percentage = (hist.at<float>(i,0)*100.0)/totalPixels;
        bins.push_back(std::make_pair(i, percentage));
    }

    // sort the bins according to percentage
    sort(bins.begin(), bins.end(),comparator());

    // compute percentile for a pixel value
    int pixel = 185;
    float sum = 0;

    for (auto b : bins)
    {
        if(b.first != pixel)
            sum += b.second;
        else
        {
            sum += b.second/2;
            break;
        }
    }

    std::cout<<"Percentile for pixel("<<pixel<<"): "<<sum<<std::endl;