您的位置:首页 > 其它

关于印象笔记的扫描宝——简单的图像背景去除(去底色)算法小结

2016-03-09 18:11 543 查看
前段时间研究了下印象笔记的扫描宝,发现它将手机拍下的照片都能处理成白板背景,而且处理的很干净,出于好奇并学习,自己琢磨出了个简易的去底色算法,虽然不能跟印象笔记的相比,但是效果也还阔以,供自己学习了,有兴趣的朋友欢迎指教。

文中测试图分别如下:

图1



图2



图3



图4



法一:伽马变换

主要思想:调整色阶,明暗图像求加;

void ls::gamma2Add(cv::Mat &src,cv::Mat &dst)
{
Mat image;
resize(src, image, Size(((float)src.cols/(float)src.rows)*krows,krows));
Scan scan;
cv::Mat dst1,dst2;
scan.gammaCorrection(image, dst1, 0.45);
scan.gammaCorrection(image, dst2, 2);
dst = dst1 + dst2;

}

效果如下:









法二:替换背景的像素值;
主要思想,首先遍历图像(遍历可以优化),统计出图像中最多的颜色像素,然后替换成255;

void changeRGB(Mat &src)
{
//        Mat image;
//        detailEnhance(src, src);
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
MatND hist = getHistogram(gray);
double maxVal = 0,minVal = 0;
//获取最大值和最小值
int hpt = static_cast<int>(0.9 * histSize[0]);
minMaxLoc(hist, &minVal, &maxVal,0,0);
cout<<minVal<<","<<maxVal<<endl;
vector<int> kChange;
//        int th = me / maxVal;
//        int nonzero = countNonZero(gray);
//        double ratio = nonzero / (double)(gray.cols * gray.rows);
//        cout<<ratio<<endl;
for (int i = 0; i < histSize[0]; i ++)
{
float binVal = hist.at<float>(i);
//cout<<binVal<<endl;
int intensity = static_cast<int>(binVal*hpt/maxVal);
if (abs(intensity - 255) < 60)
{
intensity = 255;
hist.at<float>(i) = intensity * maxVal/hpt;
}
//            if (abs(intensity - 0) > 30) {
//                intensity = 0;
//                hist.at<float>(i) = intensity * maxVal/hpt;
//            }
//

}
minMaxLoc(hist,&minVal, &maxVal,0,0);
cout<<minVal<<","<<maxVal<<endl;
for (int num = 0; num < histSize[0]; num ++)
{
if (hist.at<float>(num) >= 0.5*maxVal)//( hist.at<float>(i) >= ratio*maxVal && hist.at<float>(i) <= 1.0*maxVal)//3.63
{
kChange.push_back(num);
}
}
int nl = src.rows;
int nc = src.cols;
//        if (src.isContinuous()) {
//            nc = nc * nl;
//            nl = 1;
//        }
for (int j = 0; j < nl; j ++)
{
//            uchar *data = src.ptr<uchar>(j);
for (int l = 0; l < nc; l ++)
{
int b = 0.11 * src.at<Vec3b>(j, l)[0];
int g = 0.59 * src.at<Vec3b>(j, l)[1];
int r = 0.30 * src.at<Vec3b>(j, l)[2];
int greyVal = b + g + r;
for (int ii = 0; ii < kChange.size(); ii ++)
{
if (abs(greyVal - kChange[ii]) <= 18)//
//                    if (greyVal == kChange[ii])
{
src.at<Vec3b>(j, l)[0] = 255;
src.at<Vec3b>(j, l)[1] = 255;
src.at<Vec3b>(j, l)[2] = 255;
}
}

}
}
}

效果如下:









不难发现还是有一些瑕疵在的,希望能与大家交流讨论。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: