opencv图像倾斜校正和切边

#include<opencv2/opencv.hpp>
#include<iostream>
#include<cmath>
using namespace std;
using namespace cv;
const char input[] = "Input image";
const char output[] = "Output image";
void fileCutLine(int, void*);//对图片边缘切取
void rotateImage(int,void*);//对于图片进行旋转矫正
Mat src, dst,rotateSrc;
int main(void) {
	src = imread("..\\cutLineTest.jpg");
	rotateSrc = imread("..\\rotateTestImage.jpg");
	if (src.empty()||rotateSrc.empty()) {
		cout << "Loading image failed!" << endl;
		return -1;
	}
	pyrDown(rotateSrc, rotateSrc);
	namedWindow(input, WINDOW_AUTOSIZE);
	namedWindow(output, WINDOW_AUTOSIZE);
	int thresh = 134;
	//createTrackbar("Control threshold", output, &thresh, 255, fileCutLine);
	//fileCutLine(thresh, 0);
	createTrackbar("Rotate fix", output, &thresh, 255, rotateImage);
	rotateImage(thresh, 0);
	//imshow(input, src);
	imshow(input, rotateSrc);
	waitKey(0);
	return 0;
}
void fileCutLine(int thresh, void*) {
	Mat gray;
	Mat border;
	Mat kernel = Mat(Size(3, 3), CV_8UC1);
	cvtColor(src, gray, COLOR_BGR2GRAY);
	GaussianBlur(gray, gray, Size(7, 7), 0);
	//高斯模糊降噪
	Canny(gray, border, thresh, 2 * thresh);
	//通过开操作将黑色边缘上的水映文字去掉
	morphologyEx(border, border, MORPH_OPEN, kernel);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(border, contours,hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE,Point(0,0));
	Rect mask;//最后获得的正确范围的遮罩
	//Mat temp = Mat::zeros(src.size(), CV_8UC3);
	//临时图像承载,用于观察边框
	for (int i = 0; i < contours.size(); i++){
		RotatedRect rect = minAreaRect(contours[i]);
		Point2f corner[4];
		//设置图片尺度条件,进行边缘矩形筛选
		if ((rect.size.width > src.cols*0.75)  &&  rect.size.height>src.rows*0.75) {
			rect.points(corner);
			//cout << "************************" << endl;
			line(border, corner[0], corner[1], Scalar(0, 0, 255),2);
			line(border, corner[1], corner[2], Scalar(0, 0, 255),2);
			line(border, corner[3], corner[2], Scalar(0, 0, 255),2);
			line(border, corner[3], corner[0], Scalar(0, 0, 255),2);
			mask = rect.boundingRect();//返回包含旋转矩形的矩形
		}
	}
	cout << mask.width << ‘ ‘ << mask.height << endl;
	cout << src.cols << ‘ ‘ << src.rows << endl;
	//imshow("temp", temp);
	dst = src(mask);//比较好用
	imshow(output, border);
	if (!dst.empty()) {
		imshow("Result", dst);
	}
}
//如果图片是倾斜
void rotateImage(int thresh,void*) {
	//Mat gray;
	Mat border;
	Mat kernel = Mat(Size(3, 3), CV_8UC1);
	//cvtColor(rotateSrc, gray, COLOR_BGR2GRAY);
	Canny(rotateSrc, border, thresh, 2 * thresh);
	//通过开操作将黑色边缘上的水映文字去掉
	//morphologyEx(border, border, MORPH_OPEN, kernel);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(border, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
	double angle = 0;//需要记录角度
	Point2f center=Point2f(rotateSrc.rows/2,rotateSrc.cols/2);
	Size fixSize;
	Rect mask;
	Mat temp = Mat(rotateSrc.size(),CV_8UC3);
	for (int i = 0; i < contours.size(); i++){
		RotatedRect rect = minAreaRect(contours[i]);
		//center = rect.center;
		Point2f corner[4];
		rect.points(corner);
		for (int j = 0; j < 4; j++)	{
			line(temp, corner[j], corner[(j + 1) % 4], Scalar(255,255,255), 2);
		}
		if (rect.angle != 0) {
			angle = rect.angle;
			cout << "Angle:" << angle << endl;
		}
	}
	Mat martix = getRotationMatrix2D(center, angle, 1);//得到仿射矩阵
	warpAffine(rotateSrc, dst, martix, rotateSrc.size());
	imshow("result", dst);
	imshow(output,border);
}

在调整阈值时加了traceBar,调的时候方便一些。  

结果如下(图是百度上随便找的):

原文地址:https://www.cnblogs.com/yuxi-blog/p/10827955.html

时间: 2024-10-10 09:42:42

opencv图像倾斜校正和切边的相关文章

扫描图像二维码抠图(倾斜校正 去黑边)

由于要识别扫描仪得到的图片,直接将得到的图片进行识别,并不能得到识别结果,笔者使用的是zbar类,只能正常识别只含有二维码图像的图片.于是将二维码从图中扣出来就成了工作中的一个需求. (网上有一些收费的控件具有图像预处理的功能,可以进行很好的识别) 简单的使用现有的图像边缘检测和连通域算法,并不能得到很好的效果: 例如canny边沿检测处理结果: 不过观察不难发现二维码的特点,接近于正方形的一个小方块,于是设想是否能够通过简单的画框得到该二维码的区域. 另外由于扫描是可能会产生倾斜,会导致二维码

opencv图像原地(不开辟新空间)顺时旋转90度

前一阵朋友碰到这么一道题:将图像原地顺时针旋转90度,不开辟新空间.此题看似平易(题目简短),仔细研究发现着实不容易.经过一番探索后,终于找到了正确的算法,但是当使用opencv实现时,有碰到了困难而且费了一番周折才找到问题所在. 首先,解决这个问题,先简化成原地90度旋转一M×N的矩阵A(注意不是N×N方阵).对于2×3的矩阵A = {1,2,3;4,5,6},其目标为矩阵B = {4,1;5,2;6,3}.因为是原地旋转,这里A和B应指向同一大小为6的内存空间. 这里有这样一个重要的导出公式

OpenCV &mdash;&mdash; 图像局部与部分分割(一)

背景减除 一旦背景模型建立,将背景模型和当前的图像进行比较,然后减去这些已知的背景信息,则剩下的目标物大致就是所求的前景目标了 缺点 -- 该方法基于一个不长成立的假设:所有像素点是独立的 场景建模 新的前景(物体移动的新位置) -- 旧的前景 (物体离开后留下的"空洞")-- 背景 cvInitLineIterator()  和  CV_NEXT_LINE_POINT() 对任意直线上的像素进行采样 // 从视频的一行中读出所有像素的RGB值,收集这些数值并将其分成三个文件 #inc

OpenCV &mdash;&mdash; 图像局部与分割(二)

分水岭算法 将图像中的边缘转化成"山脉",将均匀区域转化为"山谷" 分水岭算法首先计算灰度图像的梯度,这对山谷或没有纹理的盆地(亮度值低的点)的形成有效,也对山头或图像中没有主导线段的山脉(山脊对应的边缘)的形成有效.然后开始从用户指定点或算法得到的点开始"灌注"盆地知道这些区域连在一起.基于这样产生的标记就可以把区域合并到一起,合并后的区域又通过聚集的方式进行分割,好像图像被"填充"起来. cvWatershed 用 Inp

[转]OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放

[OpenCV入门教程之十三]OpenCV图像金字塔:高斯金字塔.拉普拉斯金字塔与图片尺寸缩放 2014-05-18 18:58 36007人阅读 评论(54) 收藏 举报 本文章已收录于:  OpenCV知识库 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 知乎:http

【OpenCV入门教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 知乎:http://www.zhihu.com/people/mao-xing-yun 邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本: 2.4.9 这篇文章里,我们将一起探讨图像金字塔的一

Opencv 图像读取与保存问题

本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/49737357 本文仅对 Opencv图像读取与保存进行阐述,重在探讨图像读取与保存过程中应注意的细节问题. 1 图像读取 首先看一下,imread函数的声明: // C++: Mat based Mat imread(const string& filename, int flags=1 ); // C: IplImage based

Opencv 图像叠加 添加水印

Opencv 图像叠加 添加水印 C++: void Mat::copyTo(OutputArray m) const C++: void Mat::copyTo(OutputArray m, InputArray mask) const 这个函数可以复制图像到另一个图像或矩阵上,可选参数是掩码 由于叠加的图像大小不一定相等,比如我们这里把一张小照片加到一张大照片上 我们可以在大照片上设置一个和小照片一样大的感兴趣区域 不使用掩码的时候,我们载入一张png,和一张jpg #include <op

FilterEngine 类解析——OpenCV图像滤波核心引擎(zz)

<2>FilterEngine 类解析——OpenCV图像滤波核心引擎 FilterEngine类是OpenCV关于图像滤波的主力军类,OpenCV图像滤波功能的核心引擎.各种滤波函数比如blur, GaussianBlur,到头来其实是就是在函数末尾处定义了一个Ptr<FilterEngine>类型的f,然后f->apply( src, dst )了一下而已. 这个类可以把几乎是所有的滤波操作施加到图像上.它包含了所有必要的中间缓存器.有很多和滤波相关的create系函数的