【问题标题】:Attempt to implementation Running Length Smoothing Algorithm in C++尝试在 C++ 中实现运行长度平滑算法
【发布时间】:2014-03-03 15:23:15
【问题描述】:

这是我与RLSA in C++ 相关的老问题,但我还没有得到任何帮助。

我尝试将代码从 Matlab 实现到 C++

该算法的描述:

http://crblpocr.blogspot.fr/2007/06/run-length-smoothing-algorithm-rlsa.htmlhttp://crblpocr.blogspot.fr/2007/06/determination-of-run-length-smoothing.html

此线程在 Matlab 中有 RLSA 实现:

http://mathworks.cn/matlabcentral/newsreader/view_thread/318198

MatLab 代码

    hor_thresh=20;
zeros_count=0;
one_flag=0;
hor_image=image;
for i=1:m
    for j=1:n
        if(image(i,j)==1)
            if(one_flag==1)
                if(zeros_count<=hor_thresh)
                    hor_image(i,j-zeros_count:j-1)=1;
                else
                    one_flag=0;
                end
                zeros_count=0;
            end
            one_flag=1;
        else 
            if(one_flag==1)
                zeros_count=zeros_count+1;
            end
        end
    end
end

我尝试用 C++ 代码实现

                int hor_thres = 22;
                int one_count = 0;
                int zero_flag = 0;
                Mat tmpImg = Mat(Img.size(), CV_8UC1, Scalar(0, 0, 0));
                for (int j = 0; j<Img.rows; j++){
                    for (int i = 0; i<Img.cols; j++){
                        if (Img.at<uchar>(j, i) == 0)
                        {
                            if (zero_flag == 1)
                            {
                                if (one_count <= hor_thres)
                                {           
                                    tmpText(cv::Range(j - zero_count, j), cv::Range(i, i+1)).setTo(cv::Scalar::all(255));
// I want to do the same thing in Matlab as this  image(i,j-one_count:j-1)=0;
                                }
                                else
                                {
                                    zero_flag = 1;
                                }
                                one_count = 0;
                            }
                            zero_flag = 1;
                        }
                        else
                        {
                            if (zero_flag == 1)
                            {
                                one_count = one_count + 1;
                            }
                        }
                    }
                }

这次没有错误但结果不是预期的..

问题是我想编写与

相同的 c++ 代码的方式

Matlab

tmpImg(i,j-one_count:j-1)=0;

C++

tmpText(cv::Range(j - zero_count, j), cv::Range(i, i+1)).setTo(cv::Scalar::all(255));

知道吗???

另一件事是在 Matlab 中索引从 1 开始,而 C++ 从 0 开始。

谢谢

【问题讨论】:

    标签: c++ algorithm matlab opencv


    【解决方案1】:

    OpenCV 按行/列索引,而不是 x/y,所以改为:

    if (tmpText.at<uchar>(j, i) == 0)
                          ^^^^
    

    您还需要修复使用 at&lt;T&gt;(row,col) 函数的其余代码。

    【讨论】:

    • 谢谢,我认为 Matlab hor_image(i,j-one_count:j-1)=0; 在 c++ 中实现时也存在问题 for (int col = j - one_count - 1; col &lt; j - 1; j++) { tmpTextConnected.at&lt;uchar&gt;(i - 1, col) = 0; }
    • @sayvortana 是的,就像我在上面所说的那样 “您需要修复其余代码...” ... :-)
    • 嗨@RogerRowland,我编辑了问题中的C++代码和新的错误,请看一下谢谢
    【解决方案2】:

    谢谢@Roger Rowland 我终于实现了这个算法,希望它可以帮助那些需要它的人。

                    int hor_thres = 22;
                    int zero_count = 0;
                    int one_flag = 0;
                    for (int i = 0; i<tmpImg.rows; i++){
                        for (int j = 0; j<tmpImg.cols; j++){
                            if (tmpImg.at<uchar>(i, j) == 255)
                            {
                                if (one_flag == 255)
                                {
                                    if (zero_count <= hor_thres)
                                    {
    
    
                                        tmpImg(cv::Range(i, i + 1), cv::Range(j - zero_count, j)).setTo(cv::Scalar::all(255));
                                                        }
                                    else
                                    {
                                        one_flag = 0;
                                    }
                                    zero_count = 0;
                                }
                                one_flag = 255;
                            }
                            else
                            {
                                if (one_flag == 255)
                                {
                                    zero_count = zero_count + 1;
                                }
                            }
                        }
                    }
    

    未来的建议是在不使用循环的情况下改进此实现。

    【讨论】:

      【解决方案3】:

      如果你有黑色前景和白色背景,那么希望你会发现我的实现很有用。

      水平 RLSA

      void horizontalRLSA(Mat &input, Mat &output, int thresh)
          {
              for (int j = 0; j < input.rows; j++)
              {
                  int count = 0;
                  int flag = 0;
                  for (int i = 0; i < input.cols; i++)
                  {
                      if (input.at<uchar>(j, i) == 255)
                      {
                          flag = 255;
                          count++;
                      }
                      else
                      {
                          if (flag == 255 && count <= thresh)
                          {
                              output(Rect(i - count, j, count, 1)).setTo(Scalar::all(0));
                          }
                          flag = 0;
                          count = 0;
                      }
                  }
              }
          }
      

      垂直 RLSA

      void verticalRLSA(Mat &input, Mat &output, int thresh)
          {
              for (int i = 0; i < input.cols; i++)
              {
                  int count = 0;
                  int flag = 0;
                  for (int j = 0; j < input.rows; j++)
                  {
                      if (input.at<uchar>(j, i) == 255)
                      {
                          flag = 255;
                          count++;
                      }
                      else
                      {
                          if (flag == 255 && count <= thresh)
                          {
                              output(Rect(i, j - count, 1, count)).setTo(Scalar::all(0));
                          }
                          flag = 0;
                          count = 0;
                      }
                  }
              }
          }
      

      用法

      Mat input_binary_image;
      Mat hrlsa = input_binary_image.clone();
      horizontalRLSA(input_binary_image, hrlsa, 50);
      

      【讨论】:

        猜你喜欢
        • 2014-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-11
        • 1970-01-01
        • 2018-02-17
        • 2010-12-30
        • 2014-01-04
        相关资源
        最近更新 更多