C语言数字图像处理之图像缩放

本文实例为大家分享了C语言实现图像缩放的具体代码,供大家参考,具体内容如下

1. 定义(摘自维基百科)

在计算机图形学中,图像缩放指的是通过增加或去掉像素来改变图片的尺寸。由于要在效率和图像质量比如平滑度和清晰度之间做折衷,图像缩放并不是个简单的过程。当图像尺寸增大的时候,组成图像的像素也越来越大,图像看上去就变"柔和"了。而缩小图像的时候,图像就变得平滑和清晰了。

除了为了适应显示区域而缩小图片外,图像缩小技术更多的是被用来产生预览图片。图像放大技术一般被用来令一个较小的图像填充一个大的屏幕。当你放大一张图像时,你不能可能获得更多的细节,因此图像的质量将不可避免的下降。不过也有很多技术可以保证在放大图像即增加像素的时候,图像的质量不变。

2.方法及实现

2.1 图像缩小

为了能够更好的观察效果,选用了比较小的图片(200*200)进行处理。

图像缩小相对比较简单,由于缩小必定损失信息量,所以个人感觉需要考虑的是怎么尽可能多的保留原始信息。

最简单的方法为直接选取部分数据。譬如,图像缩小一倍,则隔一行(列)取一个数据,图像缩小为原来的四分之一,则隔三行(列)取一个数据。

处理结果:

这种方式相当于直接舍去了1/2(3/4)的信息,于是尝试通过取相邻像素的平均值代替原来单纯的一个像素以尽可能多的保留原始信息。

分析:

可以看到,后者得到的图片效果明显好于前者。在进行图像缩小操作时,要考虑的是在图像信息必然损失的情况下,尽可能多的保留原始信息。

第一种处理关键代码为:

for (int i = 0; i < height; i+=3){
        for (int j = 0; j < width; j+=3){
            PicZoomOut[i / 4][j / 4] =Pic[i][j];
        }
    }

第二种处理关键代码为:

for(int i = 0; i < 100; i++){
          for(int j = 0; j < 100; j++){
                 PicZoomOut[i][j] = (Pic[i * 2][j * 2]+ Pic[i * 2 + 1][j * 2] + Pic[i * 2][j * 2 + 1] + Pic[i * 2+ 1][j * 2 + 1])/4;
          }
   }

图像缩小,第二种方法,缩为原来1/4,代码

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define height  200
#define width   200

typedef unsigned char  BYTE;    // 定义BYTE类型,占1个字节

int main(void)
{
FILE *fp = NULL;
BYTE PicZoomOut[100][100];
BYTE *ptr;
BYTE **Pic = new BYTE *[height];
for (int i = 0; i != height; ++i)
{
Pic[i] = new BYTE[width];
}

fp = fopen("1.raw", "rb");
ptr = (BYTE*)malloc(width * height * sizeof(BYTE));//创建内存
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
fread(ptr, 1, 1, fp);
Pic[i][j] = *ptr;  // 把图像输入到2维数组中,变成矩阵型式
ptr++;
}
}
fclose(fp);
for (int
i = 0; i < 50; i++)
{
for (int
j = 0; j < 50; j++)
{
PicZoomOut[i][j]
= (Pic[i * 4][j * 4]     + Pic[i * 4 + 1][j * 4]     + Pic[i * 4 + 2][j *
4]     + Pic[i * 4 + 3][j * 4] + Pic[i * 4][j * 4 + 1] + Pic[i * 4 + 1][j * 4 + 1] + Pic[i * 4 + 2][j * 4 + 1] + Pic[i * 4 + 3][j * 4 + 1] + Pic[i * 4][j * 4 + 2] + Pic[i * 4 + 1][j * 4 + 2] + Pic[i * 4 + 2][j * 4 + 2] + Pic[i * 4 + 3][j * 4 + 2] + Pic[i * 4][j * 4 + 3] + Pic[i * 4 + 1][j * 4 + 3] + Pic[i * 4 + 2][j * 4 + 3] + Pic[i * 4 + 3][j * 4 + 3])/16;
}
}
fp = fopen("output.raw", "wb");
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 50; j++)
{
fwrite(&PicZoomOut[i][j], 1, 1, fp);
}
}
fclose(fp);
return 0;
}

2.2 图像放大

为了能够更好的观察效果,选用了比较小的图片(100*100)进行处理。

图像放大由于信息量已定,所以个人感觉需要考虑的是怎么尽可能多的使用原始信息并且能呈现出比较好的放大效果。。

最简单的方法为近邻取样插值,也称零阶插值。它输出的像素灰度值就等于距离它映射到的位置最近的输入像素的灰度值。但当图像中包含像素之间灰度级有变化的细微结构时,最邻近算法会在图像中产生人为加工的痕迹。

测试如下:

放大后的图像保留了原始图像的所有细节,但结果并不让人满意,有阶梯状锯齿。于是尝试采用其他缩放方法。

双线型内插值算法是一种比较好的图像缩放算法,它充分的利用了源图中虚拟点四周的四个真实存在的像素值来共同决定目标图中的一个像素值,因此缩放效果比简单的最邻近插值要好很多。

对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v) (其中i、j均为浮点坐标的整数部分,u、v为浮点坐标的小数部分,是取值[0,1)区间的浮点数),则这个像素得值 f(i+u,j+v) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即:f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)

其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。

效果如下:

可见,相比于邻取样插值算法,这个算法的效果就好很多。不过导致了不期望的细节柔化。

在PS软件中用来图像放大的最佳算法是二次立方,测试如下:

双立方插值计算涉及到16个像素点, 而最终插值后的图像中的(x, y)处的值即为16个像素点的权重卷积之和

将上面三种算法得到的结果依次放到一起对比观察如下

分析:显然,近邻取样插值效果最差。虽然保留了原始图像的所有细节,但出现了阶梯状锯齿。双线型内插值效果与二次立方插值效果都比近邻取样插值好,二者相比,双线型内插值有一点细节柔化(比如眼珠部位)。

综上,二次立方插值效果最好。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C语言实现BMP图像开运算处理

    开运算可以把比结构元素小的特定图像细节出去,同时保证不产生全局的几何失真.滤掉比结构元素小的突刺,切断细长搭接而起到分离作用. 运算:用B开启A就是选出了A中某些与B相匹配的点,这些点可由完全包含在A中的结构元素B的平移得到.也就是先腐蚀后加膨胀. #include <stdio.h> #include <stdlib.h> #include <Windows.h> int main(int* argc, char** argv) { FILE* fp = fopen(

  • C语言实现BMP图像处理(直方图均衡化)

    本文实例为大家分享了C语言实现BMP图像直方图均衡化处理的具体代码,供大家参考,具体内容如下 计算步骤: 1)统计各灰度值的概率: 2)计算了累积概率直方图(CDF): 3)取整扩展:Tk = int[ (L-1)*Tk]; #include <Windows.h> #include <stdlib.h> #include <stdio.h> #include <math.h> int main(int* argc, char** argv) { FILE*

  • C语言实现BMP图像处理(哈夫曼编码)

    哈夫曼(Huffman)编码是一种常用的压缩编码方法,是 Huffman 于 1952 年为压缩文本文件建立的.它的基本原理是频繁使用的数据用较短的代码代替,较少使用的数据用较长的代码代替,每个数据的代码各不相同.这些代码都是二进制码,且码的长度是可变的. 下面给出具体的 Huffman 编码算法: (1) 首先统计出每个符号出现的频率,上例 S0 到 S7 的出现频率分别为 4/14,3/14,2/14,1/14,1/14,1/14,1/14,1/14. (2) 从左到右把上述频率按从小到大的

  • C语言实现BMP图像处理(彩色图转灰度图)

    我们知道真彩图不带调色板,每个象素用 3 个字节,表示 R.G.B 三个分量.所以处理很简单,根据 R.G.B 的值求出 Y 值后,将 R.G.B 值都赋值成 Y,写入新图即可. 在YUV 的颜色表示方法中,Y 分量的物理含义就是亮度,它含了灰度图(grayscale)的所有信息,只用 Y 分量就完全能够表示出一幅灰度图来.YUV 和RGB 之间有着如下的对应关系: 再来看看带调色板的彩色图,我们知道位图中的数据只是对应调色板中的一个索引值,我们只需要将调色板中的彩色变成灰度,形成新调色板,而位

  • C语言数字图像处理之直方图均衡化

    本文实例为大家分享了C语言直方图均衡化的具体代码,供大家参考,具体内容如下 原理 直方图均衡化(Histogram Equalization) 又称直方图平坦化,实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等.这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较平的分段直方图:如果输出数据分段值较小的话,会产生粗略分类的视觉效果. 直方图是表示数字图像中每一灰度出现频率的统计关系.直方图能给出图像灰度范围.每个

  • C语言数字图像处理之图像缩放

    本文实例为大家分享了C语言实现图像缩放的具体代码,供大家参考,具体内容如下 1. 定义(摘自维基百科) 在计算机图形学中,图像缩放指的是通过增加或去掉像素来改变图片的尺寸.由于要在效率和图像质量比如平滑度和清晰度之间做折衷,图像缩放并不是个简单的过程.当图像尺寸增大的时候,组成图像的像素也越来越大,图像看上去就变"柔和"了.而缩小图像的时候,图像就变得平滑和清晰了. 除了为了适应显示区域而缩小图片外,图像缩小技术更多的是被用来产生预览图片.图像放大技术一般被用来令一个较小的图像填充一个

  • C#数字图像处理之图像缩放的方法

    本文实例讲述了C#数字图像处理之图像缩放的方法.分享给大家供大家参考.具体如下: //定义图像缩放函数 private static Bitmap ZoomP(Bitmap a, float s, float v) { Bitmap bmp = new Bitmap((int)(a.Width * s), (int)(a.Height * v), System.Drawing.Imaging.PixelFormat.Format24bppRgb); Graphics g = Graphics.F

  • python数字图像处理实现图像的形变与缩放

    目录 skimage的transform模块 1.改变图片尺寸resize 2.按比例缩放rescale 3.旋转 rotate 4.图像金字塔 skimage的transform模块 图像的形变与缩放,使用的是skimage的transform模块,函数比较多,功能齐全. 1.改变图片尺寸resize 函数格式为: skimage.transform.resize(image,output_shape) image: 需要改变尺寸的图片 output_shape: 新的图片尺寸 from sk

  • C#数字图像处理之图像二值化(彩色变黑白)的方法

    本文实例讲述了C#数字图像处理之图像二值化(彩色变黑白)的方法.分享给大家供大家参考.具体如下: //定义图像二值化函数 private static Bitmap PBinary(Bitmap src,int v) { int w = src.Width; int h = src.Height; Bitmap dstBitmap = new Bitmap(src.Width ,src.Height ,System .Drawing .Imaging .PixelFormat .Format24

  • python数字图像处理之图像的批量处理

    目录 正文 图片集合函数 批量读取 批量转换为灰度图 批量保存 正文 有些时候,我们不仅要对一张图片进行处理,可能还会对一批图片处理.这时候,我们可以通过循环来执行处理,也可以调用程序自带的图片集合来处理. 图片集合函数 skimage.io.ImageCollection(load_pattern,load_func=None) 这个函数是放在io模块内的,带两个参数,第一个参数load_pattern, 表示图片组的路径,可以是一个str字符串.第二个参数load_func是一个回调函数,我

  • python数字图像处理之图像自动阈值分割示例

    目录 引言 1.threshold_otsu 2.threshold_yen 3.threshold_li 4.threshold_isodata 5.threshold_adaptive 引言 图像阈值分割是一种广泛应用的分割技术,利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域(目标区域和背景区域)的组合,选取一个比较合理的阈值,以确定图像中每个像素点应该属于目标区域还是背景区域,从而产生相应的二值图像. 在skimage库中,阈值分割的功能是放在fi

  • python数字图像处理之图像简单滤波实现

    目录 引言 1.sobel算子 2.roberts算子 3.scharr算子 4.prewitt算子 5.canny算子 6.gabor滤波 7.gaussian滤波 8.median 9.水平.垂直边缘检测 10.交叉边缘检测 引言 对图像进行滤波,可以有两种效果:一种是平滑滤波,用来抑制噪声:另一种是微分算子,可以用来检测边缘和特征提取. skimage库中通过filters模块进行滤波操作. 1.sobel算子 sobel算子可用来检测边缘 函数格式为:skimage.filters.so

  • Java数字图像处理之图像灰度处理

    本文实例为大家分享了Java数字图像处理基础之图像灰度处理,供大家参考,具体内容如下 一.简介 图像灰度化处理可以作为图像处理的预处理步骤,在图像处理中是十分重要的一件事.灰度图像上每个像素的颜色值又称为灰度,指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0. 灰度转换公式: int gray = (int)(color.getRed() * 0.299 + color.getGreen() * 0.587 + color.getBlue() *0.114); 我们只是需要

  • Python图像处理之图像的缩放、旋转与翻转实现方法示例

    本文实例讲述了Python图像处理之图像的缩放.旋转与翻转实现方法.分享给大家供大家参考,具体如下: 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图像的缩放 图像的缩放使用resize()成员函数,直接在入参中指定缩放后的尺寸即可,示例如下: #-*- coding: UTF-8 -*- from PIL import Image #读取图像 im = Image.open("lenna.j

随机推荐