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=0∑nsinc(n−x)=sin((n−x)∗Π)/(n−x)/Π
其中 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] &