Ask Your Question
1

how to smooth edge of text

asked 2017-04-12 13:47:30 -0600

Habib gravatar image

updated 2017-04-16 02:09:37 -0600

Hello How to smooth edge of text in binary image, based on threshold.Something like anti-aliasing by openCv? example

image description

edit retag flag offensive close merge delete

Comments

Your link is invalid so I have no idea what you try to achieve here.

StevenPuttemans gravatar imageStevenPuttemans ( 2017-04-14 07:29:47 -0600 )edit
1

Excuse me,i fix example link.

Habib gravatar imageHabib ( 2017-04-15 01:42:14 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
6

answered 2017-04-15 22:50:52 -0600

updated 2017-04-18 21:14:13 -0600

Here is a Sample implementation of Contour based and Image based edge-smoothing algorithms! Hope this helps!

#include <iostream>
#include "opencv2/opencv.hpp"

#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
    string FileName_S="D:\\Image samples\\Input.png";

    Mat mSource,mThres,mResult,mSmoothEdge;
    mSource= imread(FileName_S,0);

//Source Image

image description

    RNG rng(12345);

    if(mSource.empty())
    {
        cout<<"[Error] Invalid Input Image!";
        return 0;
    }
    mSmoothEdge= mSource.clone();
    mSmoothEdge.setTo(0);
    threshold(mSource,mThres,125,255,THRESH_BINARY);
    imshow("Source mThres",mThres);

image description

    cvtColor(mSource,mResult,COLOR_GRAY2BGR);

    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    vector<vector<Point>> contours_Smoothed;
    int Radius=1;
    double Sigma=2.0;

    findContours( mThres.clone(), contours, hierarchy, RETR_TREE, CV_CHAIN_APPROX_SIMPLE );

    //Smoothing Contour Points using Gaussian Smooth!
    SmoothContours(contours,contours_Smoothed,Radius,Sigma);

    for( size_t i = 0; i< contours.size(); i++ )
    {
        /*Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
        drawContours( mResult, contours, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );*/
        if(hierarchy[i][2]<0)//These are inner most child contours
        {
            drawContours( mSmoothEdge, contours_Smoothed, i, Scalar(0), -1, LINE_AA, vector<Vec4i>(), 0, Point() );
        }
        if(hierarchy[i][3]<0)//These are outer most parent contours
        {
            drawContours( mSmoothEdge, contours_Smoothed, i, Scalar(255), -1, LINE_AA, vector<Vec4i>(), 0, Point() );
        }
    }

    //imshow("Source Image",mResult);
    imshow("1) Smooth Edge Points",mSmoothEdge);

image description

    //Smoothing Edge using Modified Unsharp Masking
    mSmoothEdge.setTo(0);
    SmoothEdgeSingleChannel(mThres,mSmoothEdge,2.5,1.0,254);
    imshow("2) Smooth Edges",mSmoothEdge);

image description

    waitKey();
}

bool SmoothEdge( Mat mInput_Bgr,Mat &mOutput_Bgr, double amount, double radius, uchar Threshold) 
{
    if(mInput_Bgr.empty())
    {
        return 0;
    }

    if(radius<1)
        radius=1;

    Mat mInput,mOutput;
    Mat mChannel[3];

    split(mInput_Bgr,mChannel);

    for (int i = 0; i < 3; i++)
    {
        mInput= mChannel[i];
        SmoothEdgeSingleChannel(mInput,mOutput,amount, radius,Threshold); 
        mOutput.copyTo(mChannel[i]);
    }
    merge(mChannel,3,mOutput_Bgr);


    return true;
}

bool SmoothEdgeSingleChannel( Mat mInput,Mat &mOutput, double amount, double radius, uchar Threshold) 
{
    if(mInput.empty())
    {
        return 0;
    }
    if(radius<1)
        radius=1;

    Mat mGSmooth,mDiff,mAbsDiff;
    mOutput = Mat(mInput.size(),mInput.type());

    GaussianBlur(mInput,mGSmooth,Size(0,0),radius); 
    //imshow("mGSmooth",mGSmooth);

    subtract(mGSmooth,mInput,mDiff);
    //imshow("mDiff",mDiff);

    mDiff*=amount;
    threshold(abs(2* mDiff),mAbsDiff,Threshold,255,THRESH_BINARY_INV);

    mDiff.setTo(Scalar(0),mAbsDiff);
    //imshow("mDiff Multiplied",mDiff);

    add(mInput,mDiff,mOutput);

    return true;
}

//Credits: http://stackoverflow.com/questions/34527349/non-connecting-morphological-filter/34535023#34535023
bool SmoothContours(vector<vector<Point>> contours_Src,vector<vector<Point>> &contours_Smooth,int Radius,double Sigma )
{
    if(contours_Src.size()==0)
        return false;
    int FilterSize = 2 * Radius + 1;

    for (int id = 0; id < contours_Src.size(); id++)
    {
        size_t len = contours_Src[id].size() + 2 * Radius;
        size_t idx = (contours_Src[id].size() - Radius);
        vector<float> x, y;
        vector<float> xFilt, yFilt;
        vector<Point> contours_Smooth_Curr;

        for (size_t i = 0; i < len; i++)
        {
            x.push_back(contours_Src[id][(idx + i) % contours_Src[id].size()].x);
            y.push_back(contours_Src[id][(idx + i) % contours_Src[id].size()].y);
        }

        GaussianBlur(x, xFilt, Size(FilterSize, FilterSize), Sigma, Sigma);
        GaussianBlur(y, yFilt, Size(FilterSize, FilterSize), Sigma, Sigma);

        for (size_t i = Radius; i < contours_Src[id].size() + Radius; i++)
        {
            contours_Smooth_Curr.push_back(Point(xFilt[i], yFilt[i]));
        }
        contours_Smooth.push_back(contours_Smooth_Curr);
    }


    return true;
}
edit flag offensive delete link more

Comments

I can not compile your code ,I think this part of your code has problem :

drawContours( mSmoothEdge, contours_Smoothed, i, Scalar(0), -1, LINE_AA, vector<Vec4i>(), 0, Point() );
Habib gravatar imageHabib ( 2017-04-18 02:26:02 -0600 )edit

At the first, Thanks; I try your code ,LINE_AA is undefined. and my result is not like what you've sent.result image almost is not acceptable infact .

Habib gravatar imageHabib ( 2017-04-18 10:06:35 -0600 )edit

Thank you,what about colored images?

Habib gravatar imageHabib ( 2017-04-19 01:18:49 -0600 )edit

@Balaji R how about supplying a tutorial based on this answer?

StevenPuttemans gravatar imageStevenPuttemans ( 2017-04-19 04:56:45 -0600 )edit
1

Great, it would be awesome! I'll try to make it as a tutorial as soon as possible!

Balaji R gravatar imageBalaji R ( 2017-04-19 05:09:02 -0600 )edit

Thanks in advance!

StevenPuttemans gravatar imageStevenPuttemans ( 2017-04-19 08:39:12 -0600 )edit

@Balaji R,I ask how can this code be generalized to colored images.

Habib gravatar imageHabib ( 2017-04-19 11:34:37 -0600 )edit

@Habib, how about just converting your image from color to grayscale, then applying a local thresholding to get a binary image?

StevenPuttemans gravatar imageStevenPuttemans ( 2017-04-20 04:52:28 -0600 )edit

@StevenPuttemans No ,How to smooth edge of text in colored image ?

Habib gravatar imageHabib ( 2017-04-21 07:56:13 -0600 )edit

@Habib, your NO makes no sense. I gave you a possible solution ...

StevenPuttemans gravatar imageStevenPuttemans ( 2017-04-21 08:12:15 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2017-04-12 13:47:30 -0600

Seen: 3,937 times

Last updated: Apr 18 '17