Skip to content

Instantly share code, notes, and snippets.

@unot
Last active December 12, 2015 12:39
Show Gist options
  • Save unot/4773336 to your computer and use it in GitHub Desktop.
Save unot/4773336 to your computer and use it in GitHub Desktop.
スキャン画像の余白を圧縮&文字を太く&1024x758にリサイズするプログラム。要OpenCV。変数erodeitを変更すると圧縮度合いが変わります。
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
int main(int argc, char* argv[])
{
if(argc==1) {
std::cout << "Usage: compressSpace input_img" << std::endl;
return 0;
}
cv::Mat src_img = cv::imread(argv[1], 0);
if(src_img.empty()) {
std::cerr << "Image Load Failed!" << std::endl;
return -1;
}
static const std::string fileName_ext = argv[1];
static std::string fileName(fileName_ext, 0, fileName_ext.size()-4);
static const std::string empty_string;
static std::ostringstream os;
// border whitening
int border = (int)(src_img.rows*2.0/100);
cv::rectangle(src_img, cv::Point(0,0),
cv::Point(src_img.cols, src_img.rows),
cv::Scalar::all(255), border, CV_AA);
cv::Mat dst_img, compRows, compCols;
// binarize
cv::Mat bin_img, fg_img, rev_img, char_img, compressed;
cv::threshold(src_img, bin_img, 0, 255, cv::THRESH_BINARY|cv::THRESH_OTSU);
cv::bitwise_xor(src_img, cv::Scalar::all(255), rev_img);
// denoise
cv::threshold(rev_img, char_img, 0, 255, cv::THRESH_TOZERO|cv::THRESH_OTSU);
// dilate
cv::pyrUp(char_img, rev_img);
cv::dilate(rev_img, char_img, cv::Mat(), cv::Point(-1,-1), 1);
cv::bitwise_xor(char_img, cv::Scalar::all(255), rev_img);
// cv::dilate(rev_img, rev_img, cv::Mat(), cv::Point(-1,-1), 1);
cv::resize(rev_img, char_img, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR);
int erodeit = 17;
cv::erode(bin_img, fg_img, cv::Mat(), cv::Point(-1,-1), erodeit);
// compress height
double minVal = 255.0;
for(int y=0; y<fg_img.rows; y++)
{
compRows.push_back(char_img.row(y));
cv::minMaxLoc(fg_img.row(y), &minVal, NULL, NULL, NULL);
if(minVal == 255.0)
compRows.pop_back(1);
}
// rotate
cv::Mat rot_img, rot_fg_img;
cv::transpose(fg_img, rot_fg_img);
cv::transpose(compRows, rot_img);
// compress width
minVal = 255.0;
for(int x=0; x<rot_img.rows; x++)
{
compCols.push_back(rot_img.row(x));
cv::minMaxLoc(rot_fg_img.row(x), &minVal, NULL, NULL, NULL);
if(minVal == 255)
compCols.pop_back(1);
}
cv::transpose(compCols, dst_img);
// unsharp mask
// cv::GaussianBlur(dst_img, sharpen, cv::Size(0,0), 3);
// cv::addWeighted(dst_img, 1.5, sharpen, -0.5, 0, sharpen);
os << fileName << "_compress.png";
double mag = std::min<double>(758.0/dst_img.cols, 1024.0/dst_img.rows);
cv::resize(dst_img, compressed, cv::Size(), mag, mag, cv::INTER_LINEAR);
cv::imwrite(os.str(), compressed);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment