2014-02-06 20 views
1

这是我的老问题,涉及RLSA in C++,但我还没有得到任何帮助。试图在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

MatLabCode

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)); 

Anyidea ???

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

谢谢

回答

0

所有的感谢@罗格罗兰我终于实现了这个算法,希望它能帮助那些需要它的人。

   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; 
          } 
         } 
        } 
       } 

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

2

由行/列,而不是X/Y的OpenCV索引开始,所以这样做,而不是:

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

您需要修复使用at<T>(row,col)函数的其他代码。

+0

谢谢,我觉得也有这个以及0123发行Matlab的 'hor_image(I,J-one_count:J-1)= 0;' 当我在C++实现 '为(INT COL = j的 - one_count - 1; col (i-1,col)= 0; }' – sayvortana

+0

@sayvortana是的,就像我上面说的*“你需要修复你的代码的其余部分......”* ... :-) –

+0

嗨@RogerRowland,我编辑了问题中的C++代码,我得到的新错误请看看谢谢 – sayvortana

1

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

Horisontal 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);