OpenCV-基于傅里叶变换的旋转文本图像矫正实现

代码实现:

int main()
{
	cv::Mat image = cv::imread("1.jpg", 0);
	if (image.empty()) return -1;
	//图像尺寸转换
	const int nrows = image.rows, ncols = image.cols;
	//获取DFT尺寸
	int crows = cv::getOptimalDFTSize(nrows), ccols = cv::getOptimalDFTSize(ncols);
	//复制图层,超过边界区域填充为0
	cv::Mat result;
	cv::copyMakeBorder(image, result, 0, crows - nrows, 0, ccols - ncols, cv::BORDER_CONSTANT, cv::Scalar(0));
	//为傅里叶变换的结果(实部和虚部)分配存储空间
	cv::Mat groupMat[] = { cv::Mat_<float>(result), cv::Mat::zeros(result.size(), CV_32F) };
	//通道合并
	cv::Mat mergeMat;
	cv::merge(groupMat, 2, mergeMat);
	//DFT变换
	cv::dft(mergeMat, mergeMat);
	//分离通道
	cv::split(mergeMat, groupMat);
	//计算幅值
	cv::magnitude(groupMat[0], groupMat[1], groupMat[0]);
	cv::Mat dftresult;
	dftresult = groupMat[0].clone();
	//对数变换
	dftresult += 1;
	cv::log(dftresult, dftresult);
	//裁剪幅度图
	dftresult = dftresult(cv::Rect(0, 0, ncols, nrows));
	//归一化
	cv::normalize(dftresult, dftresult, 0, 1, CV_MINMAX);
	//图像类型转换
	//输出图像类型,尺寸缩放因子,尺寸偏移量
	dftresult.convertTo(dftresult, CV_8UC1, 255, 0);
	//中心变换
	int cx = dftresult.cols / 2, cy = dftresult.rows / 2;
	cv::Mat tmp;
	//Top-Left-为每个象限创建ROI
	cv::Mat q0(dftresult, cv::Rect(0, 0, cx, cy));
	//Bottom-Left
	cv::Mat q1(dftresult, cv::Rect(0, cy, cx, cy));
	//Top-Right
	cv::Mat q2(dftresult, cv::Rect(cx, 0, cx, cy));
	//Bottom-right
	cv::Mat q3(dftresult, cv::Rect(cx, cy, cx, cy));
	q0.copyTo(tmp), q3.copyTo(q0), tmp.copyTo(q3);
	q1.copyTo(tmp), q2.copyTo(q1), tmp.copyTo(q2);
	cv::imshow("dftresult", dftresult);
	//固定阈值二值化
	cv::Mat binaryMat;
	cv::threshold(dftresult, binaryMat, 122, 255, CV_THRESH_BINARY);
	cv::imshow("binaryMat", binaryMat);
	//霍夫变换
	//输入图像,输出线向量(线向量由两个元素组成,第一个是距离原点的距离,第二个是线旋转角)
	//累积像素的距离分辨率,累积弧度的角度分辨率
	//要检测一条直线所需最少的曲线交点
	//多尺度霍夫变换参数,是一个距离分辨率因子
	std::vector<cv::Vec2f> lines;
	cv::HoughLines(binaryMat, lines, 1, CV_PI / 180, 100, 0, 0);
	//检测线个数
	std::cout << lines.size() << std::endl;
	//绘制检测线
	cv::Mat houghMat(binaryMat.size(), CV_8UC3);
	for (int i = 0; i < lines.size(); i++)
	{
		float rho = lines[i][0], theta = lines[i][1];
		cv::Point pt1, pt2;
		//坐标变换生成线表达式
		doub
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值