双三次插值算法 放大图片 图片直接花了 求解

习惯左手 2016-04-15 11:59:40
代码如下 图片是花的,求大神帮助




/双三次插值算法的图形缩放。
//------------------------------------------------------------------------------------------------




//-----------------------------【头文件、命名空间包含部分】------------------------------
// 描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <math.h>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

//-----------------------------------【全局函数声明部分】-----------------------------------
// 描述:全局函数声明
//-----------------------------------------------------------------------------------------------
void ShowHelpText();

float spline(float x);
void howi(Mat& inputImage, Mat& outputImage);
//--------------------------------------【main( )函数】---------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
system("color 9F");
//【1】创建原始图并显示
Mat srcImage = imread("1.jpg");
imshow("原始图像",srcImage);

//【2】按原始图的参数规格来创建创建效果图
Mat dstImage,tmpImage;
tmpImage=srcImage;
dstImage.create(srcImage.rows*2,srcImage.cols*2,srcImage.type());//效果图的大小、类型与原图片相同 */

ShowHelpText();

//【3】记录起始时间
double time0 = static_cast<double>(getTickCount());

//【4】放大函数
howi(tmpImage,dstImage);
//resize函数
// resize(tmpImage,dstImage,Size(tmpImage.cols*2,tmpImage.rows*2),(0,0),(0,0),3);
//【5】计算运行时间并输出
time0 = ((double)getTickCount() - time0)/getTickFrequency();
cout<<"此方法运行时间为: "<<time0<<"秒"<<endl; //输出运行时间

//【6】显示效果图
imshow("效果图",dstImage);
waitKey(0);
}


//----------------------------------【放大函数】-------------------------------
// 描述:双三次插值算法的图形缩放大
//----------------------------------------------------------------------------------------------
void howi(Mat& inputImage, Mat& outputImage)
{

int newheight=inputImage.rows*2;
int newwidth=inputImage.cols*2;
float f_newy,f_newx;
int oldy,oldx;
int old16R[4][4],old16G[4][4],old16B[4][4];
float newR=0.0f, newG=0.0f, newB=0.0f;
int i_x,i_y;//浮点型坐标的整数部分
float u,v;//浮点型坐标的小数部分
float A[4],C[4];
float r1,r2;
printf("图片高度=%d,宽度=%d",newheight, newwidth);
for(int newy=0;newy<newwidth;newy++)
{ f_newy=(float)newy/2;
i_y=(int)floor(f_newy);
v=f_newy-(float)floor(f_newy);

for(int newx=0;newx<newheight;newx++)
{

f_newx=(float)newx/2;
i_x=(int)floor(f_newx);
u=f_newx-(float)floor(f_newx);
A[0]=spline(u+1.0f);
A[1]=spline(u);
A[2]=spline(1.0f-u);
A[3]=spline(2.0f-u);
C[0]=spline(v+1.0f);
C[1]=spline(v);
C[2]=spline(1.0f-v);
C[3]=spline(2.0f-v);

for(int i=0;i<4;i++)
{ //r1 = spline((float) i - v);
for(int j=0;j<4;j++)
{
//r2 = spline(-1.0f*((float)j - u));
oldy=i_y+j-1;
oldx=i_x+i-1;
if(oldx<0) oldx=0;
if(oldy<0) oldy=0;
if(oldx>=inputImage.rows) oldx=inputImage.rows-1;
if(oldy>=inputImage.rows) oldy=inputImage.cols-1;


old16R[i][j]=inputImage.at<Vec3b>(oldx,oldy)[2];
old16G[i][j]=inputImage.at<Vec3b>(oldx,oldy)[1];
old16B[i][j]=inputImage.at<Vec3b>(oldx,oldy)[0];
}
}
for(int n=0;n<4;n++)
{
for(int m=0;m<4;m++)
{
newR+=A[m]*old16R[m][n]*C[n];
newG+=A[m]*old16G[m][n]*C[n];
newB+=A[m]*old16B[m][n]*C[n];
}
}

outputImage.at<Vec3b>(newx,newy)[0]= newB; //蓝色通道
outputImage.at<Vec3b>(newx,newy)[1] =newG; //绿色通道
outputImage.at<Vec3b>(newx,newy)[2] =newR; //红是通道


}
}


}


//-------------------------------【ShowHelpText( )函数】--------------------------------
// 描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
void ShowHelpText()
{
//输出欢迎信息和OpenCV版本
printf("\n\n\t\t\t基于双三次插值算法的图形缩放\n");
printf("\n\n\t\t\t --\n");
printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION );
printf("\n\n ----------------------------------------------------------------------------\n");
}


float spline(float x)
{
float result;
if(fabs(x)>=0&&fabs(x)<1)
{
result=1-2*fabs(x)*fabs(x)+fabs(x)*fabs(x)*fabs(x);

}
else if(fabs(x)>=1&&fabs(x)<2)
{
result=4-8*fabs(x)+5*fabs(x)*fabs(x)-fabs(x)*fabs(x)*fabs(x);

}
else if(fabs(x)>=2)
{

result=0;
}
return result;
}
...全文
350 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2016-04-18
  • 打赏
  • 举报
回复
在矩形 -sx/2+x,-sy/2+y sx/2+x,sy/2+y 范围内的点是有贡献的点
lm_whales 2016-04-16
  • 打赏
  • 举报
回复
那就采用效率低,但是效果好的方法吧 假设 sx,sy 分别是 x,y 方向的缩放比 求出,dst 的每个像素在 src 的位置 对 dst每个像素 点(x,y) 有贡献的点在 -sx/2+x, x,sx/3+x,-sy/2+y,sy/2+y 之间的所有像素点 在这个范围的所有点求出加权平均值,可以用 立方插值相同的方法
lm_whales 2016-04-16
  • 打赏
  • 举报
回复
插值的时候,注意不要溢出
lm_whales 2016-04-15
  • 打赏
  • 举报
回复
图像缩放,应该求出目标图像在原图像的位置,用这个位置做参数 进行缩放 在该位置周围找若干图像点,进行插值 如果缩放比例太大,图像细腻,走样在所难免 如果要求清晰,就不能采用简单的插值了 而应该对每个对目标图像有贡献的点, 做加权平均值,方法可以和Cube 插值相同,但是计算量不是一般的大
习惯左手 2016-04-15
  • 打赏
  • 举报
回复
赵4老师 2016-04-15
  • 打赏
  • 举报
回复
建议楼主使用PS创建一个尺寸尽量小比如4像素x3像素的图片辅助单步调试你的代码。
习惯左手 2016-04-15
  • 打赏
  • 举报
回复
我就是这么做的啊 不知道哪里出了问题

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧