函数原型
void cv::warpAffine (
InputArray src,
OutputArray dst,
InputArray M,
Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
)
参数介绍
INTER_NEAAREST | 最临近插值算法 |
---|---|
INTER_LINEAR | 线性插值算法 |
INTER_CUBIC | 双立方插值算法 |
INTER_AREA | 区域插值算法(使用像素区域关系的重采样时图像抽取的首选方法,但是当图像被放大,它类似与INTER_NEAREST方法) |
INTER_LANCZOS4 | Lanczos插值算法(超过8×8)邻域的插值算法 |
INTER_MAX | 用于插值的掩模板 |
WARP_FILL_OUTLIERS | 标志位,用于填充目标图像的像素值,如果其中一些值对应于原图像中的异常值,那么这些值将被设置为0 |
WARP_INVERSE_MAP | 标志位,反变换 |
函数api
Mat cv::getRotationMatrix2D ( Point2f center,
double angle,
double scale
)
参数介绍
#include
#include
#include
#include
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
#define PIC_PATH "/work/opencv_pic/"
#define PIC_NAME "case1.jpg"
int cur_val = 190;
int max_val = 255;
Mat src,gray_src,dst;
void find_roi(int,void*);
int main (void)
{
//获取完整的图片路径及名称
string pic = string(PIC_PATH)+string(PIC_NAME);
//打印图片路径
cout << "pic path is :"<<pic<<endl;
//读取图片
src = imread(pic);
//判断图片是否存在
if(src.empty())
{
cout<<"pic is not exist!!!!"<<endl;
return -1;
}
namedWindow("src pic",WINDOW_AUTOSIZE);
imshow("src pic",src);
createTrackbar("阈值调整","src pic",&cur_val,max_val,find_roi);
find_roi(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}
void find_roi(int,void*)
{
cvtColor(src,gray_src,COLOR_BGR2GRAY);
Mat canny_output;
Canny(gray_src,canny_output,cur_val,cur_val*2,3);
namedWindow("canny pic",WINDOW_AUTOSIZE);
imshow("canny pic",canny_output);
Mat recimg;
vector<vector<Point>> contours; //定义轮廓集合
vector<Vec4i> hireachy; //定义轮廓之间的索引
//查找轮廓
findContours(canny_output,contours,hireachy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));
//查找轮廓限制最基本范围 目测最大轮廓不应小于以下值
int minW = src.cols*0.2;
int minH = src.rows*0.55;
dst = Mat::zeros(src.size(),CV_8UC3);
float angle; //轮廓外包矩形的旋转角度
RotatedRect minrect; //轮廓外包的最小矩形
for(size_t i=0;i<contours.size();i++)
{
minrect = minAreaRect(contours[i]); //获取轮廓外包矩形
angle = minrect.angle; //获取矩形角度
if(minrect.size.width>minW && minrect.size.height > minH) //判断矩形是不是那个比较大的
{
Point2f pts[4]; //矩形四个角点
minrect.points(pts); //获取角点
Mat contour_rect = Mat::zeros(src.size(),CV_8UC3);
//绘制外接最大矩形
for(size_t i=0;i<4;i++)
line(contour_rect,pts[i],pts[(i+1)%4],Scalar(0,0,255),3);
//显示矩形
namedWindow("最大边缘",WINDOW_AUTOSIZE);
imshow("最大边缘",contour_rect);
}
}
cout << "矩形角度" << angle <<endl;
Point2f center(src.cols / 2, src.rows / 2);
Mat rotm = getRotationMatrix2D(center, angle, 1.0); //获取仿射变换矩阵
Mat dst;
warpAffine(src, dst, rotm, src.size(), INTER_LINEAR, 0, Scalar(255, 255, 255)); // 进行图像旋转操作
//imwrite("123.png", dst); //将校正后的图像保存下来
imshow("Correct Image", dst);
}
将纠正后的图片存储下来,基本属于再次运行一遍代码,即可得到文档本身,得到去除白边的文档
#include
#include
#include
#include
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
#define PIC_PATH "/work/opencv_pic/"
#define PIC_NAME "case1.jpg"
int cur_val = 190;
int max_val = 255;
Mat src,gray_src,dst;
void find_roi(int,void*);
void cut_eg(int,void*);
int main (void)
{
//获取完整的图片路径及名称
string pic = string(PIC_PATH)+string(PIC_NAME);
//打印图片路径
cout << "pic path is :"<<pic<<endl;
//读取图片
src = imread(pic);
//判断图片是否存在
if(src.empty())
{
cout<<"pic is not exist!!!!"<<endl;
return -1;
}
namedWindow("src pic",WINDOW_AUTOSIZE);
imshow("src pic",src);
//createTrackbar("阈值调整","src pic",&cur_val,max_val,find_roi);
createTrackbar("阈值调整","src pic",&cur_val,max_val,cut_eg);
//find_roi(0,0);
cut_eg(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}
void find_roi(int,void*)
{
cvtColor(src,gray_src,COLOR_BGR2GRAY);
Mat canny_output;
Canny(gray_src,canny_output,cur_val,cur_val*2,3);
namedWindow("canny pic",WINDOW_AUTOSIZE);
imshow("canny pic",canny_output);
Mat recimg;
vector<vector<Point>> contours; //定义轮廓集合
vector<Vec4i> hireachy; //定义轮廓之间的索引
//查找轮廓
findContours(canny_output,contours,hireachy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));
//查找轮廓限制最基本范围 目测最大轮廓不应小于以下值
int minW = src.cols*0.2;
int minH = src.rows*0.55;
dst = Mat::zeros(src.size(),CV_8UC3);
float angle; //轮廓外包矩形的旋转角度
RotatedRect minrect; //轮廓外包的最小矩形
for(size_t i=0;i<contours.size();i++)
{
minrect = minAreaRect(contours[i]); //获取轮廓外包矩形
angle = minrect.angle; //获取矩形角度
if(minrect.size.width>minW && minrect.size.height > minH) //判断矩形是不是那个比较大的
{
Point2f pts[4]; //矩形四个角点
minrect.points(pts); //获取角点
Mat contour_rect = Mat::zeros(src.size(),CV_8UC3);
//绘制外接最大矩形
for(size_t i=0;i<4;i++)
line(contour_rect,pts[i],pts[(i+1)%4],Scalar(0,0,255),3);
//显示矩形
namedWindow("最大边缘",WINDOW_AUTOSIZE);
imshow("最大边缘",contour_rect);
}
}
cout << "矩形角度" << angle <<endl;
Point2f center(src.cols / 2, src.rows / 2);
Mat rotm = getRotationMatrix2D(center, 0, 1.0); //获取仿射变换矩阵
Mat dst;
warpAffine(src, dst, rotm, src.size(), INTER_LINEAR, 0, Scalar(255, 255, 255)); // 进行图像旋转操作
//imwrite("123.png", dst); //将校正后的图像保存下来
imshow("Correct Image", dst);
}
void cut_eg(int,void*)
{
cvtColor(src,gray_src,COLOR_BGR2GRAY);
Mat canny_output;
Canny(gray_src,canny_output,cur_val,cur_val*2,3);
namedWindow("canny pic",WINDOW_AUTOSIZE);
imshow("canny pic",canny_output);
Mat recimg;
vector<vector<Point>> contours; //定义轮廓集合
vector<Vec4i> hireachy; //定义轮廓之间的索引
//查找轮廓
findContours(canny_output,contours,hireachy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));
//查找轮廓限制最基本范围 目测最大轮廓不应小于以下值
int minW = src.cols*0.2;
int minH = src.rows*0.5;
dst = Mat::zeros(src.size(),CV_8UC3);
RotatedRect minrect; //轮廓外包的最小矩形
Rect bbox;
for(size_t i=0;i<contours.size();i++)
{
minrect = minAreaRect(contours[i]); //获取轮廓外包矩形
if(minrect.size.width>minW && minrect.size.height > minH) //判断矩形是不是那个比较大的
{
Point2f pts[4]; //矩形四个角点
minrect.points(pts); //获取角点
Mat contour_rect = Mat::zeros(src.size(),CV_8UC3);
Mat vertices; // 定义一个4行2列的单通道float类型的Mat,用来存储旋转矩形的四个顶点
boxPoints(minrect, vertices); // 计算旋转矩形的四个顶点坐标
bbox = boundingRect(vertices); //找到输入点集的最小外包直立矩形,返回Rect类型
//绘制外接最大矩形
for(size_t i=0;i<4;i++)
line(contour_rect,pts[i],pts[(i+1)%4],Scalar(0,0,255),3);
//显示矩形
namedWindow("最大边缘",WINDOW_AUTOSIZE);
imshow("最大边缘",contour_rect);
}
}
if (bbox.width > 0 && bbox.height > 0 )
{
Mat roiImg = src(bbox); //从原图中截取兴趣区域
namedWindow("roi_win", WINDOW_AUTOSIZE);
imshow("roi_win", roiImg);
}
}