在 OpenCV 中选择强度最高的像素

发布于 2024-09-17 23:57:20 字数 101 浏览 5 评论 0原文

谁能帮我找出 opencv 中灰色图像中前 1%(或者说前 100 个像素)最亮的像素及其位置。因为 cvMinMaxLoc() 只给出最亮的像素位置。

非常感谢任何帮助。

Can anyone help me to find out the top 1% (or say top 100 pixels)brightest pixels with their locations of a gray image in opencv. because cvMinMaxLoc() gives only brightest pixel location.

Any help is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心凉怎暖 2024-09-24 23:57:20

这是一种简单但无效/愚蠢的方法:

for i=1:100
  get brightest pixel using cvMinMaxLoc 
  store location
  set it to a value of zero
end

如果您不介意效率,那么这应该可行。

您还应该检查 cvInRangeS 以查找定义低阈值和高阈值的类似值的其他像素。

this is a simple yet unneficient/stupid way to do it:

for i=1:100
  get brightest pixel using cvMinMaxLoc 
  store location
  set it to a value of zero
end

if you don't mind about efficiency this should work.

you should also check cvInRangeS to find other pixels of similar values defining low and high thresholds.

终止放荡 2024-09-24 23:57:20

您需要根据直方图计算亮度阈值。然后迭代像素以获得足够亮以满足阈值的位置。下面的程序将阈值应用于图像并显示结果以进行演示:

#!/usr/bin/env python3

import sys
import cv2
import matplotlib.pyplot as plt

if __name__ == '__main__':
    if len(sys.argv) != 2 or any(s in sys.argv for s in ['-h', '--help', '-?']):
        print('usage: {} <img>'.format(sys.argv[0]))
        exit()
    img = cv2.imread(sys.argv[1], cv2.IMREAD_GRAYSCALE)
    hi_percentage = 0.01 # we want we the hi_percentage brightest pixels
    # * histogram
    hist = cv2.calcHist([img], [0], None, [256], [0, 256]).flatten()
    # * find brightness threshold
    # here: highest thresh for including at least hi_percentage image pixels,
    #       maybe you want to modify it for lowest threshold with for including
    #       at most hi_percentage pixels
    total_count = img.shape[0] * img.shape[1]  # height * width
    target_count = hi_percentage * total_count # bright pixels we look for
    summed = 0
    for i in range(255, 0, -1):
        summed += int(hist[i])
        if target_count <= summed:
            hi_thresh = i
            break
    else:
        hi_thresh = 0
    # * apply threshold & display result for demonstration purposes:
    filtered_img = cv2.threshold(img, hi_thresh, 0, cv2.THRESH_TOZERO)[1]
    plt.subplot(121)
    plt.imshow(img, cmap='gray')
    plt.subplot(122)
    plt.imshow(filtered_img, cmap='gray')
    plt.axis('off')
    plt.tight_layout()
    plt.show()

You need to calculate the brightness threshold from the histogram. Then you iterate through the pixels to get those positions that are bright enough to satisfy the threshold. The program below instead applies the threshold to the image and displays the result for demonstration purposes:

#!/usr/bin/env python3

import sys
import cv2
import matplotlib.pyplot as plt

if __name__ == '__main__':
    if len(sys.argv) != 2 or any(s in sys.argv for s in ['-h', '--help', '-?']):
        print('usage: {} <img>'.format(sys.argv[0]))
        exit()
    img = cv2.imread(sys.argv[1], cv2.IMREAD_GRAYSCALE)
    hi_percentage = 0.01 # we want we the hi_percentage brightest pixels
    # * histogram
    hist = cv2.calcHist([img], [0], None, [256], [0, 256]).flatten()
    # * find brightness threshold
    # here: highest thresh for including at least hi_percentage image pixels,
    #       maybe you want to modify it for lowest threshold with for including
    #       at most hi_percentage pixels
    total_count = img.shape[0] * img.shape[1]  # height * width
    target_count = hi_percentage * total_count # bright pixels we look for
    summed = 0
    for i in range(255, 0, -1):
        summed += int(hist[i])
        if target_count <= summed:
            hi_thresh = i
            break
    else:
        hi_thresh = 0
    # * apply threshold & display result for demonstration purposes:
    filtered_img = cv2.threshold(img, hi_thresh, 0, cv2.THRESH_TOZERO)[1]
    plt.subplot(121)
    plt.imshow(img, cmap='gray')
    plt.subplot(122)
    plt.imshow(filtered_img, cmap='gray')
    plt.axis('off')
    plt.tight_layout()
    plt.show()
离去的眼神 2024-09-24 23:57:20

C++ 版本基于发布的一些其他想法:

// filter the brightest n pixels from a grayscale img, return a new mat
cv::Mat filter_brightest( const cv::Mat& src, int n ) {

    CV_Assert( src.channels() == 1 );
    CV_Assert( src.type() == CV_8UC1 );

    cv::Mat result={};

    // simple histogram
    std::vector<int> histogram(256,0); 
    for(int i=0; i< int(src.rows*src.cols); ++i) 
        histogram[src.at<uchar>(i)]++;

    // find max threshold value (pixels from [0-max_threshold] will be removed)
    int max_threshold = (int)histogram.size() - 1;
    for ( ; max_threshold >= 0 && n > 0; --max_threshold ) {
        n -= histogram[max_threshold];
    }

    if ( max_threshold < 0 )  // nothing to do
        src.copyTo(result);
    else     
        cv::threshold(src, result, max_threshold, 0., cv::THRESH_TOZERO);

    return result;
}

使用示例:获取前 1%

auto top1 = filter_brightest( img, int((img.rows*img.cols) * .01) );

C++ version based upon some of the other ideas posted:

// filter the brightest n pixels from a grayscale img, return a new mat
cv::Mat filter_brightest( const cv::Mat& src, int n ) {

    CV_Assert( src.channels() == 1 );
    CV_Assert( src.type() == CV_8UC1 );

    cv::Mat result={};

    // simple histogram
    std::vector<int> histogram(256,0); 
    for(int i=0; i< int(src.rows*src.cols); ++i) 
        histogram[src.at<uchar>(i)]++;

    // find max threshold value (pixels from [0-max_threshold] will be removed)
    int max_threshold = (int)histogram.size() - 1;
    for ( ; max_threshold >= 0 && n > 0; --max_threshold ) {
        n -= histogram[max_threshold];
    }

    if ( max_threshold < 0 )  // nothing to do
        src.copyTo(result);
    else     
        cv::threshold(src, result, max_threshold, 0., cv::THRESH_TOZERO);

    return result;
}

Usage example: get top 1%

auto top1 = filter_brightest( img, int((img.rows*img.cols) * .01) );
鹿童谣 2024-09-24 23:57:20

尝试使用 cvThreshold 代替。

Try using cvThreshold instead.

寂寞美少年 2024-09-24 23:57:20

最合乎逻辑的方法是迭代整个图片,然后获取像素的 max 和 min 值。
然后选择一个阈值,该阈值将为您提供所需的百分比(在您的情况下为 1%)。
之后再次迭代并保存高于给定阈值的每个像素的 ij 坐标。
这样,您只需迭代矩阵两次,而不是 100 次(或 1% 的像素次),然后选择最亮的并将其删除。

OpenCV 垫是多维数组。灰度图像是二维数组,其值从0到255。
您可以像这样迭代矩阵。
<代码>
for(int i=0;i < mat.height();i++)
for(int j=0;j < mat.width();j++)
垫[i][j];

Well the most logical way is to iterate the whole picture, then get the max and min value of the pixels.
Then chose a threshold which will give you the desired percent(1% in your case).
After that iterate again and save the i and j coordinates of each pixel above the given threshold.
This way you'll iterate the matrix only two times instead of 100(or 1% of the pixels times) and choosing the brightest and deleting it.

OpenCV mats are multidimensional arrays. Gray image is two dimensional array with values from 0 to 255.
You can iterate trough the matrix like this.

for(int i=0;i < mat.height();i++)
for(int j=0;j < mat.width();j++)
mat[i][j];

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文