Skip to content

Instantly share code, notes, and snippets.

@jaydp17
Last active December 11, 2015 04:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaydp17/4545342 to your computer and use it in GitHub Desktop.
Save jaydp17/4545342 to your computer and use it in GitHub Desktop.
#include <QCoreApplication>
#include <opencv.hpp>
#include <QDebug>
double compute_skew(QString filename);
void deskew(QString filename, double angle);
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString filename = "m8.jpg";
deskew(filename,compute_skew(filename));
return a.exec();
}
double compute_skew(QString filename){
cv::Mat src = cv::imread(filename.toStdString(),0);
cv::Size size = src.size();
// inverting black & white
cv::bitwise_not(src,src);
std::vector<cv::Vec4i> lines;
cv::HoughLinesP(src,lines,1,CV_PI/180,100,size.width/2.f,20);
cv::Mat disp_lines(size, CV_8UC1, cv::Scalar(0,0,0));
double angle = 0;
unsigned nb_lines = lines.size();
for(unsigned i = 0; i< nb_lines; i++){
cv::line(disp_lines,cv::Point(lines[i][0],lines[i][1]),cv::Point(lines[i][2],lines[i][3]),cv::Scalar(255,0,0));
angle += atan2((double)lines[i][3] - lines[i][1],(double)lines[i][2] - lines[i][0]);
}
angle /= nb_lines; // mean angle, in radians.
angle = ( angle * 180 )/ CV_PI;
qDebug() << "File " << filename << ": " << angle;
return angle;
// can be used for debug purpose
// cv::imshow(filename.toStdString(), disp_lines);
// cv::waitKey(0);
// cv::destroyWindow(filename.toStdString());
}
void deskew(QString filename, double angle){
cv::Mat img = cv::imread(filename.toStdString(),0);
cv::bitwise_not(img,img);
std::vector<cv::Point> points;
cv::Mat_<uchar>::iterator it = img.begin<uchar>();
cv::Mat_<uchar>::iterator end = img.end<uchar>();
for(;it != end;it++){
if(*it){
points.push_back(it.pos());
}
}
// rotated box
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
cv::Mat rot_mat = cv::getRotationMatrix2D(box.center, angle, 1);
cv::Mat rotated;
cv::warpAffine(img, rotated, rot_mat, img.size(), cv::INTER_CUBIC);
cv::Size box_size = box.size;
if (box.angle < -45.){
std::swap(box_size.width, box_size.height);
}
cv::Mat cropped;
cv::getRectSubPix(rotated, box_size, box.center, cropped);
// cropped mat will contain the text with minimal margins
cv::imwrite("ms_cropped.jpg",cropped);
qDebug() << "image written";
}
@jaydp17
Copy link
Author

jaydp17 commented Jan 16, 2013

you can convert to c++ if u don't hv Qt installed..
i) just change all the instances of QString with std::string
ii) remove all calls to ".toStdString()".
iii) replace qDebug() with std::cout
iv) finally remove QCoreApplication line..

The above code gives you a rotated image with all the margins cut down to minimum.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment