简体   繁体   English

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

[英]Mapping pixels/elements to percentiles (C++/OpenCV)

I am using OpenCV and I have the following problem I wish to solve on an image. 我正在使用OpenCV,但我想在图像上解决以下问题。 However, my question doesn't have to be restricted to OpenCV if it is an issue, it could simply be more general c++ on, say, vectors. 但是,如果这是一个问题,我的问题并不仅限于OpenCV,它可以是向量上更通用的c ++。

The problem 问题

I want to map the pixel values of an input image (or elements of an input vector) into an output image (or vector) of same size. 我想将输入图像(或输入向量的元素)的像素值映射到相同大小的输出图像(或向量)。 Each element of the output should contain the percentile* of the corresponding element in the input. 输出的每个元素应包含输入中相应元素的百分比*。

My question is 我的问题是

How would I code an implementation of this problem? 我将如何编码此问题的实现? (In c++ or OpenCV) (在c ++或OpenCV中)

Example

I will show an example of a one-dimensional image, just for simplicity. 为了简单起见,我将展示一维图像的示例。

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

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

Performance? 性能?

I'm writing code for an analysis of images that may be a few hundred by a few hundred. 我正在编写用于分析可能几百乘几百的图像的代码。 I assume that my problem is possible in O(n log n), but I don't think even O(n^2) would be an issue (where n is the total number of elements in the image/vector). 我假设我的问题可能在O(n log n)中出现,但我认为即使O(n ^ 2)也不会成为问题(其中n是图像/矢量中元素的总数)。 However, if precise percentiles cause too much issues with the complexity, I'm okay with having a certain number of bins instead. 但是,如果精确的百分位数导致太多的复杂性问题,那么我可以使用一定数量的垃圾箱。


(*) I know that there are a few different ways of conceptualizing percentile, whether you round up or down et cetera. (*)我知道,无论是向上舍入还是向下舍入,都有几种不同的概念化百分位数。 This is of no importance to me. 这对我来说并不重要。 Whatever way works. 无论采用哪种方式。

I am not sure it this is what you're looking for but this a naive implementation of percentile for image pixel values. 我不确定这不是您要查找的内容,但这是图像像素值百分位数的幼稚实现。

    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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM