如何找到与特定像素数相对应的像素值? [英] How to find the pixel value that corresponds to a specific number of pixels?

查看:122
本文介绍了如何找到与特定像素数相对应的像素值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我在OpenCV中有一个灰度图像.

Assume that I have a grayscale image in OpenCV.

我想找到一个值,以使图像中像素的5%值大于该值.

I want to find a value so that 5% of pixels in the images have a value greater than it.

我可以遍历像素并找到具有相同值的像素数量,然后从结果中找到像素%5高于我的值的值,但是我正在寻找一种更快的方法. OpenCV中有这种技术吗?

I can iterate over pixels and find number of pixels with the same value and then from the result find the value that %5 of pixel are above my value, but I am looking for a faster way to do this. Is there any such technique in OpenCV?

我认为直方图会有所帮助,但是我不确定如何使用它.

I think histogram would help, but I am not sure how I can use it.

推荐答案

您需要:

  1. 计算像素值的累积直方图
  2. 查找值大于像素总数的95%(100-5)的bin.

鉴于均匀随机生成的图像,您将得到如下直方图:

Given an image uniformly random generated, you get an histogram like:

和类似的累积直方图(您需要找到第一个bin的值在蓝线上):

and the cumulative histogram like (you need to find the first bin whose value is over the blue line):

然后,您需要找到正确的纸槽.您可以使用 std :: lower_bound 函数找到正确的值,然后 std :: distance 来找到相应的bin号(也就是您想要的值)找). (请注意,使用lower_bound时,您会发现其值是greater or equal到给定值的元素.您可以使用

Then you need to find the proper bin. You can use std::lower_bound function to find the correct value, and std::distance to find the corresponding bin number (aka the value you want to find). (Please note that with lower_bound you'll find the element whose value is greater or equal to the given value. You can use upper_bound to find the element whose value is strictly greater then the given value)

在这种情况下,结果为242,从255*0.95 = 242.25开始,这对于从0到255的均匀分布是有意义的.

In this case it results to be 242, which make sense for an uniform distribution from 0 to 255, since 255*0.95 = 242.25.

检查完整代码:

#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>

using namespace std;
using namespace cv;

void drawHist(const vector<int>& data, Mat3b& dst, int binSize = 3, int height = 0, int ref_value = -1)
{
    int max_value = *max_element(data.begin(), data.end());
    int rows = 0;
    int cols = 0;
    float scale = 1;
    if (height == 0) {
        rows = max_value + 10;
    }
    else {
        rows = height; 
        scale = float(height) / (max_value + 10);
    }
    cols = data.size() * binSize;
    dst = Mat3b(rows, cols, Vec3b(0, 0, 0));
    for (int i = 0; i < data.size(); ++i)
    {
        int h = rows - int(scale * data[i]);
        rectangle(dst, Point(i*binSize, h), Point((i + 1)*binSize - 1, rows), (i % 2) ? Scalar(0, 100, 255) : Scalar(0, 0, 255), CV_FILLED);
    }

    if (ref_value >= 0)
    {
        int h = rows - int(scale * ref_value);
        line(dst, Point(0, h), Point(cols, h), Scalar(255,0,0));
    }
}

int main()
{

    Mat1b src(100, 100);
    randu(src, Scalar(0), Scalar(255));

    int percent = 5; // percent % of pixel values are above a val
    int val;  // I need to find this value


    int n = src.rows * src.cols; // Total number of pixels
    int th = cvRound((100 - percent) / 100.f * n);  // Number of pixels below val

    // Histogram
    vector<int> hist(256, 0);
    for (int r = 0; r < src.rows; ++r) {
        for (int c = 0; c < src.cols; ++c) {
            hist[src(r, c)]++;
        }
    }

    // Cumulative histogram
    vector<int> cum = hist;
    for (int i = 1; i < hist.size(); ++i) {
        cum[i] = cum[i - 1] + hist[i];
    }

    // lower_bound returns an iterator pointing to the first element
    // that is not less than (i.e. greater or equal to) th.
    val =  distance(cum.begin(), lower_bound(cum.begin(), cum.end(), th));


    // Plot histograms
    Mat3b plotHist, plotCum;
    drawHist(hist, plotHist, 3, 300);
    drawHist(cum, plotCum, 3, 300, *lower_bound(cum.begin(), cum.end(), th));

    cout << "Value: " << val;

    imshow("Hist", plotHist);
    imshow("Cum", plotCum);
    waitKey();

    return 0;
}

注意

  • The histogram drawing function is an upgrade from a former version I posted here
  • You can use calcHist to compute the histograms, but I personally find easier to use the aforementioned method for 1D histograms.

这篇关于如何找到与特定像素数相对应的像素值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆