c++图像处理 skew算法

c++图像处理

不定期更新
第一例 图像扭曲的C++实现



前言

本内容针对图像做水平、垂向扭曲,实现算法包括线性插值、卷积,注意的问题不卷积的边界处理及边缘锯齿。


一、基于线性插值的图像扭曲

直接上代码
下面展示一些 内联代码片

// 水平扭曲
//Mat 为openvc图像结构,所以需要加入openvc库
using namespace cv;
Mat HoriSkew3(Mat image, double delt) {
	//Mat dst(image);
	int row = image.rows;
	int col = image.cols;
	int rownew = image.rows;
	int colnew =  delt>=0?(int)ceil(col + row * delt): (int)ceil(col - row * delt);
	Mat dst = Mat::zeros(rownew, colnew, CV_32FC3);
	if (delt >= 0) {
		for (int h = 0; h < row; ++h)
		{
			for (int w = (int)floor(h * delt); w < (int)ceil(col + h * delt); ++w)
			{
				int lowcol = w - (int)floor(h * delt);
				int upcol = w - (int)floor(h * delt) + 1;
				if (upcol >= col) continue;
				Vec3b a = image.at<Vec3b>(h, lowcol);
				Vec3f* ptr = dst.ptr<Vec3f>(h, w); //dst.at<Vec3b>(h, w)[0] = 0;
				ptr->val[0] = image.at<Vec3b>(h, lowcol).val[0] + (h * delt - (int)floor(h * delt)) *
					(image.at<Vec3b>(h, upcol).val[0] - (float)image.at<Vec3b>(h, lowcol).val[0]);
				ptr->val[1] = image.at<Vec3b>(h, lowcol).val[1] + (h * delt - (int)floor(h * delt)) *
					(image.at<Vec3b>(h, upcol).val[1] - (float)image.at<Vec3b>(h, lowcol).val[1]);
				ptr->val[2] = image.at<Vec3b>(h, lowcol).val[2] + (h * delt - (int)floor(h * delt)) *
				(image.at<Vec3b>(h, upcol).val[2] - (float)image.at<Vec3b>(h, lowcol).val[2]);
			}
		}
	}
	else {
	delt = abs(delt);
	flip(image, image, 1);
	//复制上面代码就可以了
	/****
	水平扭曲代码
	****/
	flip(dst, dst, 1);

	}
	return dst;
}

这一部分比较简单,略过

二、使用卷积算法实现水平扭曲

1.原理

扭曲最大的问题在于:扭曲后的点不位于像素采样点上,所以解决办法为先移动最小整数点、再移动分数阶点(采用总卷积实现)。

分数阶移动原理:
h ( x ) = ∑ x = 0 n s i n c ( n − x ) = s i n ( ( n − x ) ∗ Π ) / ( n − x ) / Π h(x)= \displaystyle \sum_ {x=0}^{n}sinc(n-x)=sin((n-x)*\Pi)/(n-x)/\Pi h(x)=x=0nsinc(nx)=sin((nx)Π)/(nx)/Π
其中 x x x为分数阶,值可以是 ( 0 , 1 ) (0,1) (0,1),或者是$(-0.5,0.5),具体看如何取整数点。

代码如下(示例):

Mat HorSkewBySinc3(Mat image, double delt,int halfwind) {
   
	int row = image.rows;
	int col = image.cols;
	int rownew = image.rows;
	int colnew = delt >= 0 ? (int)ceil(col + row * delt) : (int)ceil(col - row * delt);
	Mat dst = Mat::zeros(rownew, colnew, CV_32FC3);

	//int wholeshift = (int)floor(row * delt);
	if (delt >= 0) {
   

		for (int h = 0; h < rownew; h++)
		{
   
			int wholeshift = (int)floor(h * delt);
			//整体移动
			for (int w = wholeshift; w < col + wholeshift; w++)
			{
   
				Vec3f* ptr = dst.ptr<Vec3f>(h, w);
				ptr->val[0] &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值