【问题标题】:Selecting the pixels with highest intensity in OpenCV在 OpenCV 中选择具有最高强度的像素
【发布时间】:2011-04-08 14:44:09
【问题描述】:

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

非常感谢任何帮助。

【问题讨论】:

    标签: c++ image-processing opencv pixels


    【解决方案1】:

    尝试改用cvThreshold

    【讨论】:

    • @Mark: 阈值没有帮助,你需要找出最亮的像素及其位置。
    • 它有什么帮助?首先设置阈值以将它们的强度提高到最大,然后使用您的 cvMinMaxLoc 找到它们的位置。
    • cvMinMaxLoc 只给出一个最亮像素的位置,我能找到其他具有相同强度的位置吗?
    • 哦..我的错。我以为您的意思是它为所有像素提供了(相同)最亮的强度。我不知道...您希望返回什么格式? x,y 坐标列表?为什么不按照我的建议使用二进制阈值,然后随意循环图像?实际上,如果你要循环它,你可以同时自己做阈值。
    • 是的...找到所有最亮像素的 (x,y) 坐标...有点排序但位置...
    【解决方案2】:

    这是一种简单但不完善/愚蠢的方法:

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

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

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

    【讨论】:

      【解决方案3】:

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

      #!/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()
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          基于发布的其他一些想法的 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) );
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-12-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-28
            相关资源
            最近更新 更多