Ask Your Question

Revision history [back]

i suggest the following approach as a starting point

step 1. by using the code below you will get horizontal & vertical mean graphs of the image like: image description image description

step 2. by using vertical mean graph ( showed on the first image) you can easily get four ROI ( take a look at another question)

step 3. by applying step 1 for each ROI and using horizontal mean graph you can divide each box ( or can ) image description

try to implement this approach and if you get stuck on some point please ask.

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized,gray,reduced_h,reduced_w;
    resize( img, resized, Size(), 0.25, 0.25 );

    cvtColor( resized, gray, CV_BGR2GRAY );

    reduce( gray, reduced_h, 0, REDUCE_AVG );
    reduce( gray, reduced_w, 1, REDUCE_AVG );

    GaussianBlur( reduced_h, reduced_h, Size(),3);
    GaussianBlur( reduced_w, reduced_w, Size(),3);

    Mat reduced_h_graph = resized.clone();
    Mat reduced_w_graph = resized.clone();

    for ( int i = 0; i < img.cols; i++)
    {
        line( reduced_h_graph,Point(i,0),Point(i,reduced_h.at<uchar>(0,i)),Scalar(255,255,0),1);
    }

    for ( int i = 0; i < img.rows; i++)
    {
        line( reduced_w_graph,Point(0,i),Point(reduced_w.at<uchar>(i,0),i),Scalar(0,255,0),1);
    }

    imshow("reduced_h_graph", reduced_h_graph );
    imshow("reduced_w_graph", reduced_w_graph );
    waitKey(0);
    return 0;
}

i suggest the following approach as a starting point

step 1. by using the code below you will get horizontal & vertical mean graphs of the image like: like:

image description image description

step 2. by using vertical mean graph ( showed on the first image) you can easily get four ROI ( take a look at another question)

step 3. by applying step 1 for each ROI and using horizontal mean graph you can divide each box ( or can ) )

image description

try to implement this approach and if you get stuck on some point please ask.

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized,gray,reduced_h,reduced_w;
    resize( img, resized, Size(), 0.25, 0.25 );

    cvtColor( resized, gray, CV_BGR2GRAY );

    reduce( gray, reduced_h, 0, REDUCE_AVG );
    reduce( gray, reduced_w, 1, REDUCE_AVG );

    GaussianBlur( reduced_h, reduced_h, Size(),3);
    GaussianBlur( reduced_w, reduced_w, Size(),3);

    Mat reduced_h_graph = resized.clone();
    Mat reduced_w_graph = resized.clone();

    for ( int i = 0; i < img.cols; i++)
    {
        line( reduced_h_graph,Point(i,0),Point(i,reduced_h.at<uchar>(0,i)),Scalar(255,255,0),1);
    }

    for ( int i = 0; i < img.rows; i++)
    {
        line( reduced_w_graph,Point(0,i),Point(reduced_w.at<uchar>(i,0),i),Scalar(0,255,0),1);
    }

    imshow("reduced_h_graph", reduced_h_graph );
    imshow("reduced_w_graph", reduced_w_graph );
    waitKey(0);
    return 0;
}

i suggest the following approach as a starting point

step 1. by using the code below you will get horizontal & vertical mean graphs of the image like:

image description image description

step 2. by using vertical mean graph ( showed on the first image) you can easily get four ROI ( take a look at another question)

step 3. by applying step 1 for each ROI and using horizontal mean graph you can divide each box ( or can )box

image description

try to implement this approach and if you get stuck on some point please ask.

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized,gray,reduced_h,reduced_w;
    resize( img, resized, Size(), 0.25, 0.25 );

    cvtColor( resized, gray, CV_BGR2GRAY );

    reduce( gray, reduced_h, 0, REDUCE_AVG );
    reduce( gray, reduced_w, 1, REDUCE_AVG );

    GaussianBlur( reduced_h, reduced_h, Size(),3);
    GaussianBlur( reduced_w, reduced_w, Size(),3);

    Mat reduced_h_graph = resized.clone();
    Mat reduced_w_graph = resized.clone();

    for ( int i = 0; i < img.cols; i++)
    {
        line( reduced_h_graph,Point(i,0),Point(i,reduced_h.at<uchar>(0,i)),Scalar(255,255,0),1);
    }

    for ( int i = 0; i < img.rows; i++)
    {
        line( reduced_w_graph,Point(0,i),Point(reduced_w.at<uchar>(i,0),i),Scalar(0,255,0),1);
    }

    imshow("reduced_h_graph", reduced_h_graph );
    imshow("reduced_w_graph", reduced_w_graph );
    waitKey(0);
    return 0;
}

i suggest the following approach as a starting point

step 1. by using the code below you will get horizontal & vertical mean graphs of the image like:

image description image description

step 2. by using vertical mean graph ( showed on the first image) you can easily get four ROI ( take a look at another question)

step 3. by applying step 1 for each ROI and using horizontal mean graph you can divide each box

image description

try to implement this approach and if you get stuck on some point please ask.

UPDATE 1 see updated code which has result image like

image description

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized,gray,reduced_h,reduced_w;
    resize( img, resized, Size(), 0.25, 0.25 );

    cvtColor( resized, gray, CV_BGR2GRAY );

    reduce( gray, reduced_h, 0, REDUCE_AVG );
    reduce( gray, reduced_w, 1, REDUCE_AVG );

    GaussianBlur( reduced_h, reduced_h, Size(),3);
    GaussianBlur( reduced_w, reduced_w, Size(),3);

    Mat reduced_h_graph = resized.clone();
    Mat reduced_w_graph = resized.clone();

    for ( int i = 0; i < img.cols; i++)
    {
        line( reduced_h_graph,Point(i,0),Point(i,reduced_h.at<uchar>(0,i)),Scalar(255,255,0),1);
    }

    for ( int i = 0; i < img.rows; i++)
    {
        line( reduced_w_graph,Point(0,i),Point(reduced_w.at<uchar>(i,0),i),Scalar(0,255,0),1);
    }

    imshow("reduced_h_graph", reduced_h_graph );
    imshow("reduced_w_graph", reduced_w_graph );
    waitKey(0);
    return 0;
}

UPDATE 1

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;
using namespace std;

vector<Rect> divideHW( Mat src, int dim, double threshold1, double threshold2 )
{
    Mat gray, reduced, canny;

    if( src.channels() == 1 )
    {
        gray = src;
    }

    if( src.channels() == 3 )
    {
        cvtColor( src, gray, CV_BGR2GRAY );
    }

    reduce( gray, reduced, dim, REDUCE_AVG );

    Canny( reduced, canny, threshold1, threshold2, 3, true );

    vector<Point> pts;
    findNonZero( canny, pts);

    vector<Rect> rects;

    Rect rect(0,0,gray.cols,gray.rows);
    int ref_x = 0;
    int ref_y = 0;

    for( size_t i=0; i< pts.size(); i++ )
    {
        if( dim )
        {
           rect.height = pts[i].y-ref_y;
           rects.push_back( rect );
           rect.y = pts[i].y;
           ref_y = rect.y;
           if( i == pts.size()-1 )
           {
             rect.height = gray.rows - pts[i].y;
             rects.push_back( rect );
           }
        }

        else
        {
           rect.width = pts[i].x-ref_x;
           rects.push_back( rect );
           rect.x = pts[i].x;
           ref_x = rect.x;
           if( i == pts.size()-1 )
           {
             rect.width = gray.cols - pts[i].x;
             rects.push_back( rect );
           }
        }

    }
    return rects;
}

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized;
    resize( img, resized, Size(), 0.25, 0.25 );

    vector<Rect> rois_h = divideHW( resized, 1, 0, 255 );

    for( size_t i=0; i< rois_h.size(); i++ )
    {
    Mat roi_h = resized( rois_h[i]);


        vector<Rect> rois_w = divideHW( roi_h, 0, 0, 255 );

    for( size_t j=0; j< rois_w.size(); j++ )
    {
    rois_w[j].y += rois_h[i].y;
    rectangle( resized, rois_w[j], Scalar( 0, 255, 0), 1 );
    rois_w[j].x = rois_w[j].x * 4;
    rois_w[j].y = rois_w[j].y * 4;
    rois_w[j].width = rois_w[j].width * 4;
    rois_w[j].height = rois_w[j].height * 4;

    rectangle( img, rois_w[j], Scalar( 0, 255, 0), 3 );
    }

    }
        imshow("resized result", resized );
        imshow("original result", img );
    waitKey(0);
    return 0;

}

i suggest the following approach as a starting point

step 1. by using the code below you will get horizontal & vertical mean graphs of the image like:

image description image description

step 2. by using vertical mean graph ( showed on the first image) you can easily get four ROI ( take a look at another question)

step 3. by applying step 1 for each ROI and using horizontal mean graph you can divide each box

image description

try to implement this approach and if you get stuck on some point please ask.

UPDATE 1 see updated code which has result image like

image description

this approach fails on misaligned pictures like

image description

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized,gray,reduced_h,reduced_w;
    resize( img, resized, Size(), 0.25, 0.25 );

    cvtColor( resized, gray, CV_BGR2GRAY );

    reduce( gray, reduced_h, 0, REDUCE_AVG );
    reduce( gray, reduced_w, 1, REDUCE_AVG );

    GaussianBlur( reduced_h, reduced_h, Size(),3);
    GaussianBlur( reduced_w, reduced_w, Size(),3);

    Mat reduced_h_graph = resized.clone();
    Mat reduced_w_graph = resized.clone();

    for ( int i = 0; i < img.cols; i++)
    {
        line( reduced_h_graph,Point(i,0),Point(i,reduced_h.at<uchar>(0,i)),Scalar(255,255,0),1);
    }

    for ( int i = 0; i < img.rows; i++)
    {
        line( reduced_w_graph,Point(0,i),Point(reduced_w.at<uchar>(i,0),i),Scalar(0,255,0),1);
    }

    imshow("reduced_h_graph", reduced_h_graph );
    imshow("reduced_w_graph", reduced_w_graph );
    waitKey(0);
    return 0;
}

UPDATE 1

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;
using namespace std;

vector<Rect> divideHW( Mat src, int dim, double threshold1, double threshold2 )
{
    Mat gray, reduced, canny;

    if( src.channels() == 1 )
    {
        gray = src;
    }

    if( src.channels() == 3 )
    {
        cvtColor( src, gray, CV_BGR2GRAY );
    }

    reduce( gray, reduced, dim, REDUCE_AVG );

    Canny( reduced, canny, threshold1, threshold2, 3, true );

    vector<Point> pts;
    findNonZero( canny, pts);

    vector<Rect> rects;

    Rect rect(0,0,gray.cols,gray.rows);
    int ref_x = 0;
    int ref_y = 0;

    for( size_t i=0; i< pts.size(); i++ )
    {
        if( dim )
        {
           rect.height = pts[i].y-ref_y;
           rects.push_back( rect );
           rect.y = pts[i].y;
           ref_y = rect.y;
           if( i == pts.size()-1 )
           {
             rect.height = gray.rows - pts[i].y;
             rects.push_back( rect );
           }
        }

        else
        {
           rect.width = pts[i].x-ref_x;
           rects.push_back( rect );
           rect.x = pts[i].x;
           ref_x = rect.x;
           if( i == pts.size()-1 )
           {
             rect.width = gray.cols - pts[i].x;
             rects.push_back( rect );
           }
        }

    }
    return rects;
}

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized;
    resize( img, resized, Size(), 0.25, 0.25 );

    vector<Rect> rois_h = divideHW( resized, 1, 0, 255 );

    for( size_t i=0; i< rois_h.size(); i++ )
    {
    Mat roi_h = resized( rois_h[i]);


        vector<Rect> rois_w = divideHW( roi_h, 0, 0, 255 );

    for( size_t j=0; j< rois_w.size(); j++ )
    {
    rois_w[j].y += rois_h[i].y;
    rectangle( resized, rois_w[j], Scalar( 0, 255, 0), 1 );
    rois_w[j].x = rois_w[j].x * 4;
    rois_w[j].y = rois_w[j].y * 4;
    rois_w[j].width = rois_w[j].width * 4;
    rois_w[j].height = rois_w[j].height * 4;

    rectangle( img, rois_w[j], Scalar( 0, 255, 0), 3 );
    }

    }
        imshow("resized result", resized );
        imshow("original result", img );
    waitKey(0);
    return 0;

}

i suggest the following approach as a starting point

step 1. by using the code below you will get horizontal & vertical mean graphs of the image like:

image description image description

step 2. by using vertical mean graph ( showed on the first image) you can easily get four ROI ( take a look at another question)

step 3. by applying step 1 for each ROI and using horizontal mean graph you can divide each box

image description

try to implement this approach and if you get stuck on some point please ask.

UPDATE 1 see updated code which has result image like

image description

this approach fails on misaligned pictures likelike below,

so it needs to an alignment process ( i will work on it )

image description

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized,gray,reduced_h,reduced_w;
    resize( img, resized, Size(), 0.25, 0.25 );

    cvtColor( resized, gray, CV_BGR2GRAY );

    reduce( gray, reduced_h, 0, REDUCE_AVG );
    reduce( gray, reduced_w, 1, REDUCE_AVG );

    GaussianBlur( reduced_h, reduced_h, Size(),3);
    GaussianBlur( reduced_w, reduced_w, Size(),3);

    Mat reduced_h_graph = resized.clone();
    Mat reduced_w_graph = resized.clone();

    for ( int i = 0; i < img.cols; i++)
    {
        line( reduced_h_graph,Point(i,0),Point(i,reduced_h.at<uchar>(0,i)),Scalar(255,255,0),1);
    }

    for ( int i = 0; i < img.rows; i++)
    {
        line( reduced_w_graph,Point(0,i),Point(reduced_w.at<uchar>(i,0),i),Scalar(0,255,0),1);
    }

    imshow("reduced_h_graph", reduced_h_graph );
    imshow("reduced_w_graph", reduced_w_graph );
    waitKey(0);
    return 0;
}

UPDATE 1

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;
using namespace std;

vector<Rect> divideHW( Mat src, int dim, double threshold1, double threshold2 )
{
    Mat gray, reduced, canny;

    if( src.channels() == 1 )
    {
        gray = src;
    }

    if( src.channels() == 3 )
    {
        cvtColor( src, gray, CV_BGR2GRAY );
    }

    reduce( gray, reduced, dim, REDUCE_AVG );

    Canny( reduced, canny, threshold1, threshold2, 3, true );

    vector<Point> pts;
    findNonZero( canny, pts);

    vector<Rect> rects;

    Rect rect(0,0,gray.cols,gray.rows);
    int ref_x = 0;
    int ref_y = 0;

    for( size_t i=0; i< pts.size(); i++ )
    {
        if( dim )
        {
           rect.height = pts[i].y-ref_y;
           rects.push_back( rect );
           rect.y = pts[i].y;
           ref_y = rect.y;
           if( i == pts.size()-1 )
           {
             rect.height = gray.rows - pts[i].y;
             rects.push_back( rect );
           }
        }

        else
        {
           rect.width = pts[i].x-ref_x;
           rects.push_back( rect );
           rect.x = pts[i].x;
           ref_x = rect.x;
           if( i == pts.size()-1 )
           {
             rect.width = gray.cols - pts[i].x;
             rects.push_back( rect );
           }
        }

    }
    return rects;
}

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized;
    resize( img, resized, Size(), 0.25, 0.25 );

    vector<Rect> rois_h = divideHW( resized, 1, 0, 255 );

    for( size_t i=0; i< rois_h.size(); i++ )
    {
    Mat roi_h = resized( rois_h[i]);


        vector<Rect> rois_w = divideHW( roi_h, 0, 0, 255 );

    for( size_t j=0; j< rois_w.size(); j++ )
    {
    rois_w[j].y += rois_h[i].y;
    rectangle( resized, rois_w[j], Scalar( 0, 255, 0), 1 );
    rois_w[j].x = rois_w[j].x * 4;
    rois_w[j].y = rois_w[j].y * 4;
    rois_w[j].width = rois_w[j].width * 4;
    rois_w[j].height = rois_w[j].height * 4;

    rectangle( img, rois_w[j], Scalar( 0, 255, 0), 3 );
    }

    }
        imshow("resized result", resized );
        imshow("original result", img );
    waitKey(0);
    return 0;

}

i suggest the following approach as a starting point

step 1. by using the code below you will get horizontal & vertical mean graphs of the image like:

image description image description

step 2. by using vertical mean graph ( showed on the first image) you can easily get four ROI ( take a look at another question)

step 3. by applying step 1 for each ROI and using horizontal mean graph you can divide each box

image description

try to implement this approach and if you get stuck on some point please ask.

UPDATE 1 see updated code which has result image like

image description

this approach fails on misaligned pictures like below,

so it needs to an alignment process ( i will work on it )

image description


UPDATE 2

you can keep following my further work on github


#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized,gray,reduced_h,reduced_w;
    resize( img, resized, Size(), 0.25, 0.25 );

    cvtColor( resized, gray, CV_BGR2GRAY );

    reduce( gray, reduced_h, 0, REDUCE_AVG );
    reduce( gray, reduced_w, 1, REDUCE_AVG );

    GaussianBlur( reduced_h, reduced_h, Size(),3);
    GaussianBlur( reduced_w, reduced_w, Size(),3);

    Mat reduced_h_graph = resized.clone();
    Mat reduced_w_graph = resized.clone();

    for ( int i = 0; i < img.cols; i++)
    {
        line( reduced_h_graph,Point(i,0),Point(i,reduced_h.at<uchar>(0,i)),Scalar(255,255,0),1);
    }

    for ( int i = 0; i < img.rows; i++)
    {
        line( reduced_w_graph,Point(0,i),Point(reduced_w.at<uchar>(i,0),i),Scalar(0,255,0),1);
    }

    imshow("reduced_h_graph", reduced_h_graph );
    imshow("reduced_w_graph", reduced_w_graph );
    waitKey(0);
    return 0;
}

UPDATE 1

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;
using namespace std;

vector<Rect> divideHW( Mat src, int dim, double threshold1, double threshold2 )
{
    Mat gray, reduced, canny;

    if( src.channels() == 1 )
    {
        gray = src;
    }

    if( src.channels() == 3 )
    {
        cvtColor( src, gray, CV_BGR2GRAY );
    }

    reduce( gray, reduced, dim, REDUCE_AVG );

    Canny( reduced, canny, threshold1, threshold2, 3, true );

    vector<Point> pts;
    findNonZero( canny, pts);

    vector<Rect> rects;

    Rect rect(0,0,gray.cols,gray.rows);
    int ref_x = 0;
    int ref_y = 0;

    for( size_t i=0; i< pts.size(); i++ )
    {
        if( dim )
        {
           rect.height = pts[i].y-ref_y;
           rects.push_back( rect );
           rect.y = pts[i].y;
           ref_y = rect.y;
           if( i == pts.size()-1 )
           {
             rect.height = gray.rows - pts[i].y;
             rects.push_back( rect );
           }
        }

        else
        {
           rect.width = pts[i].x-ref_x;
           rects.push_back( rect );
           rect.x = pts[i].x;
           ref_x = rect.x;
           if( i == pts.size()-1 )
           {
             rect.width = gray.cols - pts[i].x;
             rects.push_back( rect );
           }
        }

    }
    return rects;
}

int main( int argc, char** argv )
{
    Mat img = imread( argv[1] );
    if (img.empty())
        return -1;

    Mat resized;
    resize( img, resized, Size(), 0.25, 0.25 );

    vector<Rect> rois_h = divideHW( resized, 1, 0, 255 );

    for( size_t i=0; i< rois_h.size(); i++ )
    {
    Mat roi_h = resized( rois_h[i]);


        vector<Rect> rois_w = divideHW( roi_h, 0, 0, 255 );

    for( size_t j=0; j< rois_w.size(); j++ )
    {
    rois_w[j].y += rois_h[i].y;
    rectangle( resized, rois_w[j], Scalar( 0, 255, 0), 1 );
    rois_w[j].x = rois_w[j].x * 4;
    rois_w[j].y = rois_w[j].y * 4;
    rois_w[j].width = rois_w[j].width * 4;
    rois_w[j].height = rois_w[j].height * 4;

    rectangle( img, rois_w[j], Scalar( 0, 255, 0), 3 );
    }

    }
        imshow("resized result", resized );
        imshow("original result", img );
    waitKey(0);
    return 0;

}