Ex4:Image Warping and Image Morphing

Ex4:Image Warping and Image Morphing

完整代码见github地址:https://github.com/linjiafengyang/ComputerVision

作业4

测试数据

普通A4打印纸,上面可能有手写笔记或者打印内容,但是拍照时可能角度不正。(参考Dataset2)。
输出:
已经矫正好的标准普通A4纸(长宽比为A4纸的比例),并裁掉无用的其他内容,只保留完整A4纸张。
实验数据集依旧使用作业3的数据集。

说明:尽量保留A4纸上的原有信息不变或减少图像信息(原图像内容不要做缩放,A4纸的面积基本不变),以利于后期的文字识别和处理。

测试结果

以下面两张图为例:
这里写图片描述

这里写图片描述

代码文件

在作业3的基础上,先求A4纸的四个顶点,再进行Warping为标准普通A4纸,最后裁剪。

ImageWarping.h文件:

#include "CImg.h"
#include <iostream>
#include <vector>
using namespace cimg_library;
using namespace std;

struct Point {
    double x, y;
    int cnt;
    Point(double _x, double _y, int _cnt): x(_x), y(_y), cnt(_cnt) {}
};
struct Line {
    double k, b;
    Line(double _k, double _b): k(_k), b(_b) {}
    int index;
    double distance;
    Line(int _index, double _distance): index(_index), distance(_distance) {}
};
class Hough {
private:
    CImg<float> grayImage; // 灰度图
    CImg<float> blurred_img; // 高斯滤波平滑得到的图
    CImg<float> houghspace; // 霍夫空间图
    CImg<float> hough_result; // 霍夫检测图
    CImg<float> A4; // a4纸结果图
    vector<Point> peaks; // 霍夫空间直线经过最多的点
    vector<Line> lines; // 直线
    vector<Point> intersections; // 直线交点

    double sigma;
    double gradient_threshold;
    double vote_threshold;
    double peak_dis;
    int x_min, x_max, y_min, y_max;
public:
    Hough(CImg<float> srcImg, double sigma, double gradient_threshold, double vote_threshold, double peak_dis);
    CImg<float> imageWarping(CImg<float> srcImg);
    CImg<float> RGBtoGray(const CImg<float>& srcImg); // 转灰度图
    CImg<float> initHoughSpace(); // 初始化霍夫空间
    void findPeaks(); // 投票算法
    void drawLines(); // 寻找并画出直线
    void drawIntersections(); // 寻找并画出直线交点
    vector<CImg<float> > computeTransformMatrix(CImg<float> a4); // 计算变换矩阵
    CImg<float> warping(CImg<float> srcImg); // image warping
};

ImageWarping.cpp文件:

#include "ImageWarping.h"

Hough::Hough(CImg<float> srcImg, double sigma, double gradient_threshold, double vot_threshold, double peak_dis) {
    this->hough_result = srcImg;
    this->sigma = sigma;
    this->gradient_threshold = gradient_threshold;
    this->vote_threshold = vot_threshold;
    this->peak_dis = peak_dis;
    this->x_min = 0;
    this->x_max = srcImg._width - 1; // 图像宽度
    this->y_min = 0;
    this->y_max = srcImg._height - 1; // 图像高度
}
CImg<float> Hough::imageWarping(CImg<float> srcImg) {
    this->grayImage = RGBtoGray(srcImg); // 转灰度图
    this->blurred_img = grayImage.get_blur(sigma); // 高斯滤波平滑
    this->houghspace = initHoughSpace(); // 初始化霍夫空间
    findPeaks(); // 找出霍夫空间中直线经过最多的点
    drawLines(); // 寻找并画出直线
    drawIntersections(); // 寻找并画出直线交点
    //hough_result.display();
    this->A4 = warping(srcImg); // image warping
    return A4;
}
// 转灰度图
CImg<float> Hough::RGBtoGray(const CImg<float>& srcImg) {
    CImg<float> grayImage = CImg<float>(srcImg._width, srcImg._height, 1, 1, 0);
    cimg_forXY(grayImage, x, y) {
        grayImage(x, y, 0) = (int)round((double)srcImg(x, y, 0, 0) * 0.299 + 
                                    (double)srcImg(x, y, 0, 1) * 0.587 + 
                                    (double)srcImg(x, y, 0, 2) * 0.114);
    }
    return grayImage;
}
// 初始化霍夫空间
CImg<float> Hough::initHoughSpace() {
    CImgList<float> gradient =  blurred_img.get_gradient("xy", 2);

    CImg<float> gradient_x = gradient[0]; // x方向上的梯度
    CImg<float> gradient_y = gradient[1]; // y方向上的梯度

    int maxp = (int)sqrt(grayImage._width*grayImage._width + grayImage._height*grayImage._height);
    CImg<float> hough_space(360, maxp, 1, 1, 0); // 初始化hough space

    cimg_forXY(grayImage, i, j) {
        double grad = sqrt(gradient_x(i, j)*gradient_x(i, j) + gradient_y(i, j)*gradient_y(i, j));
        if (grad > gradient_threshold) {
            grayImage(i, j) = grad;
            cimg_forX(hough_space, alpha) {
                double theta = ((double)alpha*cimg::PI) / 180;
                int p = (int)(i*cos(theta) + j*sin(theta));
                if (p >= 0 && p < maxp) {
                    hough_space(alpha, p)++; // 累加矩阵
                }
            }
        }
    }
    return hough_space;
}
// 投票算法找出霍夫空间中直线经过最多的点
void Hough::findPea
  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值