尝试在C ++中实现运行长度平滑算法

时间:2014-02-06 15:27:35

标签: c++ algorithm matlab opencv

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

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

此算法的说明:

http://crblpocr.blogspot.fr/2007/06/run-length-smoothing-algorithm-rlsa.html http://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开始。

感谢

3 个答案:

答案 0 :(得分:2)

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

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

您还需要修复使用at<T>(row,col)功能的其余代码。

答案 1 :(得分:1)

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

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

答案 2 :(得分: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);