1 | initial version |
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:
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 )
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;
}
2 | No.2 Revision |
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:
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 )
)
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;
}
3 | No.3 Revision |
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:
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
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;
}
4 | No.4 Revision |
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:
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
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
#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;
}
5 | No.5 Revision |
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:
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
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
this approach fails on misaligned pictures like
#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;
}
6 | No.6 Revision |
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:
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
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
this approach fails on misaligned pictures likelike below,
so it needs to an alignment process ( i will work on it )
#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;
}
7 | No.7 Revision |
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:
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
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
this approach fails on misaligned pictures like below,
so it needs to an alignment process ( i will work on it )
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;
}