基於opencv的雙線性插值的實現(一)
阿新 • • 發佈:2019-01-27
#include <cv.h> #include <highgui.h> #include <iostream> using namespace std; float Abs(float f); void zoom(IplImage* src, IplImage* dst); int main() { // read an image IplImage* src = cvLoadImage("E://pic//view.jpg"); IplImage* dst = cvCreateImage(cvSize(1000,1000), src->depth, src->nChannels); zoom(src, dst); cvShowImage("src", src); cvShowImage("dst", dst); cvWaitKey(0); return 1; } /**************************** *返回絕對值 *****************************/ float Abs(float f) { return f>=0 ? f : -f; } /**************************** *目標: 實現影象的縮放, 使用了雙線性插值的演算法 *引數: src源影象 dst生成影象 *返回值:無 *****************************/ void zoom(IplImage* src, IplImage* dst) { int srcWidth = src->width; int srcHeight = src->height; int dstWidth = dst->width; int dstHeight = dst->height; //源影象與目標影象的寬高比例,這裡減1很重要,否則有時報錯,有時不報錯。這點困擾了我很久 const float tx = (srcWidth-1.0f)/(dstWidth-1.0f); const float ty = (srcHeight-1.0f)/(dstHeight-1.0f); CvPoint2D32f uv;//儲存源影象的浮點座標 CvPoint3D32f f1; CvPoint3D32f f2; for (int j=0; j<dstHeight-1; j++) { for (int i=0; i<dstWidth-1; i++) { uv.x = i*tx; uv.y = j*ty; int iu = (int)uv.x; int iv = (int)uv.y; f1.x = ((uchar*)(src->imageData + src->widthStep*iv))[iu*3+0] * (1-Abs(uv.x-iu))+ ((uchar*)(src->imageData + src->widthStep*iv))[(iu+1)*3+0] * (uv.x-iu); f1.y = ((uchar*)(src->imageData + src->widthStep*iv))[iu*3+1] * (1-Abs(uv.x-iu))+ ((uchar*)(src->imageData + src->widthStep*iv))[(iu+1)*3+1] * (uv.x-iu); f1.z = ((uchar*)(src->imageData + src->widthStep*iv))[iu*3+2] * (1-Abs(uv.x-iu))+ ((uchar*)(src->imageData + src->widthStep*iv))[(iu+1)*3+2] * (uv.x-iu); f2.x = ((uchar*)(src->imageData + src->widthStep*(iv+1)))[iu*3] * (1-Abs(uv.x-iu)) +((uchar*)(src->imageData + src->widthStep*(iv+1)))[(iu+1)*3] * (uv.x-iu); f2.y = ((uchar*)(src->imageData + src->widthStep*(iv+1)))[iu*3+1] * (1-Abs(uv.x-iu))+ ((uchar*)(src->imageData + src->widthStep*(iv+1)))[(iu+1)*3+1] * (uv.x-iu); f2.z = ((uchar*)(src->imageData + src->widthStep*(iv+1)))[iu*3+2] * (1-Abs(uv.x-iu))+ ((uchar*)(src->imageData + src->widthStep*(iv+1)))[(iu+1)*3+2] * (uv.x-iu); ((uchar*)(dst->imageData + dst->widthStep*j))[i*3] = f1.x*(1-Abs(uv.y-iv))+f2.x*(Abs(uv.y-iv)); ((uchar*)(dst->imageData + dst->widthStep*j))[i*3+1] = f1.y*(1-Abs(uv.y-iv))+f2.y*(Abs(uv.y-iv)); ((uchar*)(dst->imageData + dst->widthStep*j))[i*3+2] = f1.z*(1-Abs(uv.y-iv))+f2.z*(Abs(uv.y-iv)); } //這裡新增上最後一列 ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-1)*3] = ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-2)*3]; ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-1)*3+1] = ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-2)*3+1]; ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-1)*3+2] = ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-2)*3+2]; } //這裡新增上最後一行 for(int i=0; i<dstWidth*3; i++) { ((uchar*)(dst->imageData + dst->widthStep*(dstHeight-1)))[i] = ((uchar*)(dst->imageData + dst->widthStep*(dstHeight-2)))[i]; } }
效果圖: