CImage图像非整数倍放大缩小问题,,高手指点下,谢谢~!

tiankong1399 2008-10-25 01:15:13
下面是程序块,,其中alpha为放大缩小倍数,当alpha大于1时,,也就是图像的放大功能可以实现,可是,当alpha在0~1之间时,也就是图像的缩小功能不行,,提示说,堆栈被破坏,或者存在bug....可是放大都可以,缩小时为什么不行,,大家帮忙看看,算法上有没什么不对的。先谢谢了~!

inline void ImageScale(CImage *Imgn, CImage *Imgm, double alpha) //非整数倍缩放
{
struct IMAGEPARAMENT P;
RGBQUAD ColorTab[256];
int i, j, nSize;
BYTE **list, *sc;
int Dx, Dy, x1, y1, x2, y2, flag, bpd;
double p, q, a, b, c, d, t1, t2, t3;
if (ImageType(Imgm) == 2) //flag作为标志,当为1时,表示用双线性内插
flag = 1;
else
flag = 0; //为0时,表示用最近邻点法
GetImageParament(Imgm, &P);
Dx = (int) (alpha * P.nWidth);//计算结果位图宽度
Dy = (int) (alpha * P.nHeight);//计算结果位图高度
Imgn -> Destroy();
Imgn ->Create(Dx, Dy, P.nBitCount ); //建立结果位图
bpd = P.nBytesPerPixel;
if (bpd == 1) //256色图像
{
for (i = 0; i < P.nNumColors; i++)
{
GetAllPalette(Imgm, ColorTab);
SetAllPalette(Imgn, ColorTab); //复制调色板
}
}
nSize = (int) ((P.nBytesPerLine + P.nHeight * bpd) * alpha);//计算工作单元大小
sc = (BYTE*) malloc(nSize); //申请像素行工作单元
list = (BYTE**) malloc(Dy * sizeof(BYTE*)); // 申请指针数组
for (i = 0; i < P.nHeight; i++)
list[i] = (BYTE*) Imgm ->GetPixelAddress(0, 0) - i * P.nBytesPerLine;//生成二维数组
for (j = 0; j < Dy; j++)
{
q = j / alpha;
y1 = (int) q;
y2 = y1 + 1;
q = q - y1;
for (i = 0;i < Dx; i++)
{
p = i / alpha;
x1 = (int) p; //x1,y1为整数部分
x2 = x1 + 1;
p = p - x1; //p,q为小数部分
if ((x2 > P.nWidth)||(y2 > P.nHeight )) // 范围检查
continue;
if (x2 == P.nWidth ) x2--;
if (y2 == P.nHeight ) y2--;
if (flag == 0) //flag等于0,采用最近邻点法
{
if (q > 0.5) y1 = y2;
if (p > 0.5) x1 = x2;
memcpy(&sc[i * bpd], &list[y1][x1 * bpd],bpd); //从源位图复制像素数据
}
else
{ // flag等于1,双线性内插法
a = (double) list[y1][x1]; //从源位图取数据
b = (double) list[y1][x2];
c = (double) list[y2][x1];
d = (double) list[y2][x2];
t1 = (1 - p) * a + p * b; //双线性内插计算
t2 = (1 - p) * c + p * d;
t3 = (1 - q) * t1 + q * t2;
sc[i] = (BYTE) t3;
}
}
SetRectValue(Imgn, 0, j, Dx, 1, sc); //处理结果总结果位图
}
free(sc); //释放工作单元
free(list);
}
...全文
783 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
宅番茄 2011-01-18
  • 打赏
  • 举报
回复
粗略地看了一下,你的j是整数,这样q = j/alpha这一句的除法会按照整数除法运行,这样q的数值就已经是整数了。y1 = (int)q得到的y1数值和q相同。q最后会变成0。p也同理。
这样的话你生成的图像质量会有问题吧?因为双线性插值的系数是错误的,生成的结果图像可能和box filtering差不多?
mexiao 2009-05-22
  • 打赏
  • 举报
回复
不错,谢谢啊!
zgxsdkjdx 2008-10-28
  • 打赏
  • 举报
回复
看了您的程序及修改的内容,深受启发,看来似乎处理的是黑白影像,如果是彩色影像该如何处理呢?恳请指点!非常感谢
tiankong1399 2008-10-26
  • 打赏
  • 举报
回复
谢谢呀~~
laoma_hbu 2008-10-26
  • 打赏
  • 举报
回复
//修改点一:看你的程序我理解nSize的值,应该表示目标图像每行像素所占字节数。
nSize = (Dx * P.nBitCount + 31) / 32 * 4; //(int) ((P.nBytesPerLine + P.nHeight * bpd) * alpha);//计算工作单元大小
//
sc = (BYTE*) malloc(nSize);
//修改点二:list应该对应原始图像数据,list[i]应该指向原始图像第i行数据的起始位置。
list = (BYTE**) malloc(P.nHeight * sizeof(BYTE*)); //malloc(Dy * sizeof(BYTE*)); // 申请指针数组
//
//修改点三:如点二说的,list[i]指向图像第i行的起始位置。
for (i = 0; i < P.nHeight; i++)
list[i] = (BYTE*) Imgm->GetPixelAddress(0, i); // ->GetPixelAddress(0, 0) - i * P.nBytesPerLine;//生成二维数组


tiankong1399 2008-10-26
  • 打赏
  • 举报
回复
真的谢谢六楼~~~,我琢磨了几天没琢磨出来,谢谢了~~
不过还是不大明白六楼那三处为何那样子改??
laoma_hbu 2008-10-25
  • 打赏
  • 举报
回复
struct IMAGEPARAMENT P; 
RGBQUAD ColorTab[256];
int i, j, nSize;
BYTE **list, *sc;
int Dx, Dy, x1, y1, x2, y2, flag, bpd;
double p, q, a, b, c, d, t1, t2, t3;
if (ImageType(Imgm) == 2) //flag作为标志,当为1时,表示用双线性内插
flag = 1;
else
flag = 0; //为0时,表示用最近邻点法
GetImageParament(Imgm, &P);
Dx = (int) (alpha * P.nWidth);//计算结果位图宽度
Dy = (int) (alpha * P.nHeight);//计算结果位图高度
Imgn -> Destroy();
Imgn ->Create(Dx, Dy, P.nBitCount ); //建立结果位图
bpd = P.nBytesPerPixel;
if (bpd == 1) //256色图像
{
for (i = 0; i < P.nNumColors; i++)
{
GetAllPalette(Imgm, ColorTab);
SetAllPalette(Imgn, ColorTab); //复制调色板
}
}
//修改点一
nSize = (Dx * P.nBitCount + 31) / 32 * 4; //(int) ((P.nBytesPerLine + P.nHeight * bpd) * alpha);//计算工作单元大小
//
sc = (BYTE*) malloc(nSize); //申请像素行工作单元
//修改点二
list = (BYTE**) malloc(P.nHeight * sizeof(BYTE*)); //malloc(Dy * sizeof(BYTE*)); // 申请指针数组
//
//修改点三
for (i = 0; i < P.nHeight; i++)
list[i] = (BYTE*) Imgm->GetPixelAddress(0, i); // ->GetPixelAddress(0, 0) - i * P.nBytesPerLine;//生成二维数组
//
for (j = 0; j < Dy; j++)
{
q = j / alpha;
y1 = (int) q;
y2 = y1 + 1;
q = q - y1;
for (i = 0;i < Dx; i++)
{
p = i / alpha;
x1 = (int) p; //x1,y1为整数部分
x2 = x1 + 1;
p = p - x1; //p,q为小数部分
if ((x2 > P.nWidth)||(y2 > P.nHeight )) // 范围检查
continue;
if (x2 == P.nWidth ) x2--;
if (y2 == P.nHeight ) y2--;
if (flag == 0) //flag等于0,采用最近邻点法
{
if (q > 0.5) y1 = y2;
if (p > 0.5) x1 = x2;
memcpy(&sc[i * bpd], &list[y1][x1 * bpd],bpd); //从源位图复制像素数据
}
else
{ // flag等于1,双线性内插法
a = (double) list[y1][x1]; //从源位图取数据
b = (double) list[y1][x2];
c = (double) list[y2][x1];
d = (double) list[y2][x2];
t1 = (1 - p) * a + p * b; //双线性内插计算
t2 = (1 - p) * c + p * d;
t3 = (1 - q) * t1 + q * t2;
sc[i] = (BYTE) t3;
}
}
SetRectValue(Imgn, 0, j, Dx, 1, sc); //处理结果总结果位图
}
free(sc); //释放工作单元
free(list);


我修改了一下,在我这可以运行了。
tiankong1399 2008-10-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hbdycnm 的回复:]
Dx = (int) (alpha * P.nWidth);//计算结果位图宽度
Dy = (int) (alpha * P.nHeight);//计算结果位图高度
//错误可能在这里,当alpha 为0到1之间的时候,你计算出的值将永远为0。

自己一行一行的调试下好了。
[/Quote]

当alpha 为0到1之间的时候,为什么计算出的值将永远为0。

提示错误有:HEAP[ghgh.exe]: Heap block at 003BF6C8 modified at 003BFE64 past requested size of 794
Windows 已在 ghgh.exe 中触发一个断点。

其原因可能是堆被损坏,这也说明 ghgh.exe 中或它所加载的任何 DLL 中有 bug。

tiankong1399 2008-10-25
  • 打赏
  • 举报
回复
三楼的改法试过了,不行,缩小时,还是出现相同的问题
hbdycnm 2008-10-25
  • 打赏
  • 举报
回复
Dx = (int) (alpha * P.nWidth + 1);
tiankong1399 2008-10-25
  • 打赏
  • 举报
回复
的确是这两句的问题,但是,要怎么改比较妥当,,请知道的指教~!
hbdycnm 2008-10-25
  • 打赏
  • 举报
回复
Dx = (int) (alpha * P.nWidth);//计算结果位图宽度
Dy = (int) (alpha * P.nHeight);//计算结果位图高度
//错误可能在这里,当alpha 为0到1之间的时候,你计算出的值将永远为0。

自己一行一行的调试下好了。
内容概要:本文系统研究了构网型变流器的正负序阻抗解耦特性及其在弱电网环境下的稳定性表现,重点依托Matlab/Simulink仿真平台,构建了详细的阻抗数学模型,设计了解耦控制策略,并采用小信号扫频法进行频域辨识与稳定性验证。研究深入探讨了构网型变流器与传统跟网型逆变器在正负序阻抗特性上的本质差异,结合虚拟同步发电机(VSG)等先进控制技术,分析其在抑制宽频带振荡、削弱锁相环动态耦合等方面的优越性。文中不仅提供了完整的仿真模型与MATLAB代码实现,还整合了光伏、风电、储能、微电网等多类新能源系统的阻抗建模与稳定性分析资源,形成了一套面向新型电力系统稳定性的综合性技术资料体系,具有较强的科研复现与工程参考价值。; 适合人群:面向具备电力电子、电力系统自动化、新能源并网等专业背景的研究生、高校教师及工程技术人员,特别适用于从事阻抗建模、小干扰稳定性分析、宽频振荡机理研究以及撰写高水平学术论文的科研工作者。; 使用场景及目标:①掌握构网型变流器正负序阻抗建模与扫频辨识的仿真方法;②深入理解VSG等构网型控制在弱电网中提升稳定性的内在机理;③复现顶刊论文中的阻抗分析流程与稳定性判据应用;④利用提供的成熟模型与代码加速科研进程,支撑课题研究与学术成果产出。; 阅读建议:建议结合文中提供的Simulink模型与MATLAB代码,按照“理论建模—仿真搭建—扫频激励—频响提取—Nyquist判据分析”的完整流程进行实践操作,重点关注扫频信号的注入方式、频率范围设置及阻抗曲线的物理意义解读,并参考博士论文复现案例深化对复杂动态耦合问题的理解。

19,464

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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