加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C / OpenCV中的本地阈值实现

发布时间:2020-12-16 09:56:00 所属栏目:百科 来源:网络整理
导读:我想实现一个本地阈值算法,我需要你的专业知识. 我的图像大小调整为600×400,灰度. 本地化的基本思维过程: 使用每个像素拍摄的9×9 ROI对图像进行分割,并计算区域中的最大强度. 创建一个9×9内核. 条件: 如果蒙版的中心像素高于最大强度的50%,则将中心像
我想实现一个本地阈值算法,我需要你的专业知识.

我的图像大小调整为600×400,灰度.

本地化的基本思维过程:

>使用每个像素拍摄的9×9 ROI对图像进行分割,并计算区域中的最大强度.
>创建一个9×9内核.

条件:

>如果蒙版的中心像素高于最大强度的50%,则将中心像素设置为真.(应用蒙版)

我的问题是:

>我应该如何选择我的内核/面具?

cv::Mat ROI;
  cv::Mat mask(input.size(),CV_8UC1,cv::Scalar::all(0)); // create mask of 0s at first
  const int kerneldepth = 1;
  const int kernelsize = 9;
  cv::Mat kernel = cv::Mat::ones( kernelsize,kernelsize,CV_8UC1 );


//take ROI of 9x9 and apply a threshold

for( double x = 9; x < input.cols -9; x++ ){
     for( double y = 9 ; y < input.rows - 9 ; y++ ){

        try{
          double x_left = x - 4;
          double x_right = x + 4;
          double y_up = y + 4;
          double y_down = y - 4;
          double maxVal;
          double minVal;
          cv::Point anchor(kernelsize/2,kernelsize/2);

          cv::Rect ROI = cv::Rect(x_left,y_down,9,9);
          cv::Mat ROI_Mat = input(ROI);                                // a new matrix for ROI
          cv::Scalar avgPixelIntensity = cv::mean( ROI_Mat );          // calculate mean
          cv::minMaxLoc(ROI_Mat,&minVal,&maxVal);

          if( input.at<uchar>(x,y) >= 0.5*maxVal){

          cv::filter2D(input,mask,-1,kernel,anchor,0);
    } else { break;}

    }

    catch (cv::Exception &e){

        e.what();
    }


   }

  *****************************UPDATED CODE: ******************************************

    applyLocalThresh(cv::Mat &src,cv::Mat& out){
      double maxVal,minVal;
      cv::Mat output;
      int top,bottom,left,right;
      int borderType = cv::BORDER_CONSTANT;
      cv::Scalar value;
      top = (int) (9); bottom = (int) (9);
      left = (int) (9); right = (int) (9);
      output = src;
      out = src;
      value = 0;
      cv::copyMakeBorder(src,output,top,right,borderType,value);

     for(int y = 9; y < src.rows; y++) {

        for(int x = 9; x < src.cols; x ++) {

                cv::Mat ROI = src(cv::Rect(cv::Point(x-4,y-4),cv::Size(9,9)));
                cv::minMaxLoc(ROI,&maxVal);

        if(src.at<uchar>(cv::Point(x-4,y-4)) >= 0.6*maxVal){

        out.at<uchar>(cv::Point(x-4,y-4)) = 255;
    }else{
        out.at<uchar>(cv::Point(x-4,y-4));

        }
    }
}
 }

解决方法

你可以通过扩张然后在OpenCV中进行比较来做到这一点;

im = load image here;
di = dilate im with a 9x9 kernel;
bw = im > (di * 0.5); // in OpenCV,pixels of bw are set to 255 or 0

一个简单的例子用Matlab / Octave中的4×6图像和3×3内核来说明这一点:

我=

1     2     3     4     5     6
 2     3     4     5     6     7
 3     4     5     6     7     8
 4     5     6     7     8     9

di =

3     4     5     6     7     7
 4     5     6     7     8     8
 5     6     7     8     9     9
 5     6     7     8     9     9

th = di * .5

th =

1.5000    2.0000    2.5000    3.0000    3.5000    3.5000
2.0000    2.5000    3.0000    3.5000    4.0000    4.0000
2.5000    3.0000    3.5000    4.0000    4.5000    4.5000
2.5000    3.0000    3.5000    4.0000    4.5000    4.5000

bw = im>日

bw =

0     0     1     1     1     1
 0     1     1     1     1     1
 1     1     1     1     1     1
 1     1     1     1     1     1

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读