Reputation: 825
This is my old question related to RLSA in C++, but I havent got any help yet.
I tried to implement the code from Matlab to C++
The description of this algorithm :
http://crblpocr.blogspot.fr/2007/06/run-length-smoothing-algorithm-rlsa.html http://crblpocr.blogspot.fr/2007/06/determination-of-run-length-smoothing.html
There is RLSA implementation in Matlab by this thread :
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
I tried to implement in C++ Code
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;
}
}
}
}
This time no error but the result is not expected ..
The issue is the way i want to write c++ code the same thing as
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???
Another thing is in Matlab the index start from 1 while C++ start from 0.
Thank
Upvotes: 1
Views: 2269
Reputation: 3755
If you have black foreground and white background, then hope you will find my implementation useful.
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;
}
}
}
}
Vertical 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;
}
}
}
}
Usage
Mat input_binary_image;
Mat hrlsa = input_binary_image.clone();
horizontalRLSA(input_binary_image, hrlsa, 50);
Upvotes: 1
Reputation: 825
all thank you @Roger Rowland I finally implement this algorithm, hope it could help those who need it.
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;
}
}
}
}
Future suggestion is to improve this implementation without using loop.
Upvotes: 1
Reputation: 26279
OpenCV indexes by row/column, not x/y, so do this instead:
if (tmpText.at<uchar>(j, i) == 0)
^^^^
You'll need to fix the rest of your code that uses the at<T>(row,col)
function too.
Upvotes: 2