精华内容
下载资源
问答
  • 原文:http://coolketang.com/staticPhotoshop/5a98d384d50eee266a9fe31e.html1. 本节课程将为您演示,如何使用[钢笔工具],...[钢笔工具]属于矢量绘图工具,其优点是可以勾画平滑的曲线,在进行缩放或者变形之后,...

    原文:http://coolketang.com/staticPhotoshop/5a98d384d50eee266a9fe31e.html

    1. 本节课程将为您演示,如何使用[钢笔工具],勾选示例图片中的叶子。首先点击底部的[显示比例]输入框,并输入160%,放大显示示例图片。 



    2. 然后选择工具箱中的[钢笔工具]。[钢笔工具]属于矢量绘图工具,其优点是可以勾画平滑的曲线,在进行缩放或者变形之后,仍能保持平滑的效果。 


    3. 接着点击下拉箭头,设置[钢笔工具]的工作模式。 


    4. 点击选择[路径]选项,作为[钢笔工具]的工作模式,即使用[钢笔工具]绘制路径而不是形状。 


    5. 在叶子梗处点击,设定路径的起点。 


    6. 鼠标按下并向右上方滑动一段距离,添加路径上的第二个锚点,并让第二个锚点和第一个锚点,构成一段平滑的曲线。 


    7. 继续点击添加路径上的第三个锚点。 


    8. 鼠标按下,然后滑动一段距离,添加路径上的第四个锚点,并和第三个锚点构成一段平滑的曲线,使路径紧贴叶子的边缘。 


    9. 继续点击添加路径上的第五个锚点。 


    10. 鼠标按下,然后滑动一段距离,添加路径上的第六个锚点,并和第五个锚点构成一段平滑的曲线。 


    11. 继续点击添加路径上的第七个锚点。 


    12. 鼠标按下,然后滑动一段距离,添加路径上的第八个锚点,并和第七个锚点构成一段平滑的曲线,使路径紧贴叶子的边缘。 


    13. 继续点击添加路径上的第九个锚点。 


    14. 鼠标按下,然后滑动一段距离,添加路径上的第十个锚点,并和第九个锚点构成一段平滑的曲线。 


    15. 继续点击添加路径上的第十一个锚点。 


    16. 最后在起点处点击,这样您就创建了一条闭合的路径。 


    17. 观察刚才创建的路径,有些部位还有些问题,需要修复一下。鼠标长按[钢笔工具]图标,显示隐藏的工具列表。 


    18. 然后选择列表中的[添加锚点工具]。 


    19. 在需要添加锚点的位置上点击。 


    20. 这样您就在路径上添加了一个锚点。鼠标长按[添加锚点工具]图标,显示隐藏的工具列表。 


    21. 然后选择列表中的[转换点工具]。 


    22. 路径上所有的锚点当前都处于选择状态。所以在路径外部点击,取消对路径所有锚点的选择。 


    23. 鼠标按下并向右下方滑动,选择刚刚添加的新锚点。 


    24. 然后按下键盘上的快捷键。 


    25. 保持快捷键的按下状态,鼠标按下并向下方拖动选中的锚点,使该锚点处的路径,能够紧贴叶子底部的边缘。 


    26. 接着再来修复路径右侧的问题。点击选择凸出的路径。 


    27. 在方向线的一端按下鼠标,然后向上方拖动,调整凸出的路径,使其和叶子的边缘对齐。 


    28. 然后点击[路径]标签,打开路径面板。 


    29. 点击路径面板底部的[将路径作为选区载入]图标,将当前路径转换为选区。 


    30. 叶子已经被完美的选择了。接着点击[调整]图标,显示[调整]面板。 


    31. 在调整面板中,选择[自然饱和度]图标,显示[自然饱和度]设置面板,增强叶子的色彩浓度。 


    32. 在[自然饱和度]滑块上按下鼠标,并向右滑动,同时观察叶子色彩的变化。 


    33. 鼠标双击[缩放工具]图标,恢复示例图片的显示比例。 


    34. 点击[图层]图标,切换回图层面板。 


    35. 同时按下键盘上的快捷键,合并当前图层。 


    36. 最后使用键盘上的快捷键,保存最终的结果,并结束本节课程。 



    本文整理自:《Photoshop CC互动教程》,真正的
    [手把手]教学模式,用最快的速度上手Photoshop,苹果商店App Store免费下载:https://itunes.apple.com/cn/app/id822431555,或扫描本页底部的二维码。课程配套素材下载地址:资料下载



    展开全文
  • 硬件—— 0.96寸OLED显示屏模块0.91 1.3寸液晶屏供原理图12864屏 IIC/SPI

    本文内容:stm32 基于 SPI 协议连接外设 7 针的 0.96 寸 OLED 显示屏显示一些文字或者图画
    说明:虽然我是以 stm32 为例,但是文章中的代码有 Arduino、C51、MSP430、RaspberryPI、STM32 这五种例子,可以到文章中下载。
    在这里插入图片描述

    一、SPI 协议简介

    • SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率较高的场合。

    SPI 物理层

    • SPI 通讯设备之间的常用连接方式,如下图:
      在这里插入图片描述
    • SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK、MOSI、MISO,片选线为 SS 。

    SPI 协议层

    • SPI 通讯的通讯时序,如下图所示:
      在这里插入图片描述
    • 这是一个主机的通讯时序。NSS、SCK、MOSI 信号都由主机控制产生,而 MISO 的信号由从机产生,主机通过该信号线读取从机的数据。MOSI 与 MISO 的信号只在 NSS 为低电平的时候才有效,在 SCK 的每个时钟周期 MOSI 和 MISO 传输一位数据。

    更多 SPI 协议讲解请参考 B 站野火视频:https://www.bilibili.com/video/BV1ps411M7Dr?p=33

    二、实验过程

    1)实验前的准备

    硬件——

    软件——

    2)硬件连接

    • 根据注释连接管脚。
      在这里插入图片描述
      在这里插入图片描述
    • OLED 接入完毕,下面接串口。
    • 使用 USB 线连上 USB 转串口,使用杜邦线连接 SWD ,SWD 怎么连呢?继续往下看。
      在这里插入图片描述
    • 看板子的背面,这里我们只需要用杜邦线依次连接 SWCLK、GND、SWDIO、3V3 就行了。

    说明:
    NRST:异步复位脚,重置除了 RTC 的寄存器以及后备存储器的寄存器;
    SWCLK:时钟开关;
    GND:接地;
    SWDIO:输入/输出控制。
    3V3:电源。

    在这里插入图片描述

    • 杜邦线的另一端接 ST_LINK ,根据正面提示的引脚来进行接入,如下图:
      在这里插入图片描述
      在这里插入图片描述
    • 然后将两个 USB 接口插到电脑上,并打开开关(这样,板子就连通了电脑),之后可以进行程序的烧录。

    3)程序烧录

    ①下载源码

    • 这里使用到的程序是运行厂家给出的 Demo 程序,请下载:
      链接:https://pan.baidu.com/s/1HS33ftk3Pb7nWJRhBTLqUw
      提取码:57x8
    • 解压缩后,在 1-Demo 下选择相应的项目,这里我选择的是 Demo_STM32 下的 0.96inch_OLED_Demo_STM32F103ZET6_Hardware_4-wire_SPI ,stm32 指南者是 STM32F103VE ,但是没有 VE ,只有 ZE(stm32 霸道的就是 ZE,指南者跟霸道的差不多,所以就选 ZE 就行了)。
    • 双击打开 PROJECT 下的工程 OLED.uvprojx 即可。

    ②Keil 设置

    • 由于 Demo 程序是用 J-Link 烧录的,而我是用 ST-Link 烧录,所以需要设置下,其它的烧录方式自行设置。
    • 设置烧录方式。
      在这里插入图片描述
    • 然后点击 ST-Link 右边的 Settings 设置,将端口设为 SW 。
      在这里插入图片描述
    • 按照下图流程操作。
      在这里插入图片描述

    ③程序编译、烧录结果

    • 这是运行厂家的 Demo 例子,显示效果图如下:
      在这里插入图片描述
    • 下面我们需要对代码进行更改,显示出自己想要的样子。

    三、修改代码(显示自己的汉字)

    • 下面简单描述下修改代码的过程,最后面有修改完成后的工程提取链接。

    1)移植 AHT20 温湿度采集的代码

    • AHT20 温湿度采集的博客请参考:基于 I2C 协议使用 AHT20 温湿度传感器采集数据
    • 然后我们从这篇博客中移植部分代码(以下四个文件)。
      • bsp_i2c.h
      • bsp_i2c.c
      • sys.h(移植后更改了名称为 AHT20_sys.h,不然会重名)
      • sys.c(移植后更改了名称为 AHT20_sys.c,不然会重名)
    • 然后将 bsp_i2c.c 中串口输出改为了输出到 OLED 显示,自己写了个函数(我添加了头文件 gui.h ,不然无法调用显示函数)。
      在这里插入图片描述
    • 移植的过程中,我遇到了不少的问题,根据提示来更改代码或者注释掉一些函数就行了,一步一步更改。
    • 将 AHT20 温度模块连接到 STM32 上,如何连接?根据那篇 AHT20 的博客连接即可,AHT20 基于 I2C 协议,OLED 基于 SPI 协议,都连在同一个 STM32 上互不干扰。

    2)获取汉字字模

    • 要想在 OLED 上显示英文、数字,可以直接输出显示,但要是想显示中文,就必须要对中文进行编码成点阵。
    • 字模软件下载链接:https://pan.baidu.com/s/1GRe2X3p2ETJJEFwXsnV1sw
      提取码:fn8i
    • 打开应用程序后,输入自己想要的汉字,即可。
      在这里插入图片描述
    • 这里说明一下,为什么我的文字是这样的?这里需要将正向的文字左旋 90 °,然后再山下翻转,这样,OLED 上显示的文字才是正向的,至于为什么,可能和数据传输有关。
    • 其它汉字可以再继续生成字模即可(注意翻转下)。

    3)代码编辑

    • gui.c 下有个 oledfont.h 头文件,打开后,将 cfont16[] 数组内的内容修改成自己的中文文字点阵即可。
      在这里插入图片描述
    • 这里我添加的汉字字模有:张、某、人、欢、迎、来、到、重、庆、交、通、大、学、物、联、网、实、训、室、温、度、湿、:、℃、%

    说明:为什么不自己新声明一个点阵数组,而是修改呢?
    这是因为如果新加一个数组的话,是没有任何用的,因为显示汉字的那个函数,只会从 cfont16 数组中读取数据,新添加一个数组也可以,只不过自己要改的代码就会很多了,还会涉及到计算等等,这个方法是最简便的了。

    • 然后在 test.h 头文件中,声明一个自己新加的函数 void TEST_ShowMyName(void);
      在这里插入图片描述
    • 然后在 test.c 文件最后,实现这个函数。
      在这里插入图片描述

    函数说明——

    • GUI_ShowString() 的参数
      参数一:X 坐标
      参数二:Y 坐标
      参数三:字符串(ASCLL码中的)
      参数四:bit (表示字符显示格式,这里我用的 16 ,和汉字一样高)
      参数五:显示样式(1:白字黑底;0:黑字白底)
    • GUI_ShowChinese() 的参数
      参数一:X 坐标
      参数二:Y 坐标
      参数三:汉字点阵大小(这里使用的是 16×16 的,参数应该是 16)
      参数四:要显示的汉字
      参数五:显示样式(1:白字黑底;0:黑字白底)
    • 然后编辑 main.c 文件中的代码。
    • 调用刚刚新添加的函数,然后注释掉 white 循环中的所有函数即可。
      在这里插入图片描述

    4)显示结果

    四、总结

    • 其实说实话,这个实验从头到尾,对于这个 SPI 协议并没有了解多少,入门小白,出门还是小白,整个文章的过程就是调用函数,修改变量而已,就好比学会了怎么吃饭,却不知道怎么做饭,对于嵌入式开发的同志们,这是极大的弊端,要深入分析,由于我还是大学生,时间不太多,就不花费时间写文章分析代码了,注释都很全,慢慢学,只要头发没掉光,你就还没学到头!
    • 如果想真正了解 SPI 协议如何通讯的,还是要深入分析一下这个代码,并看看相关的 SPI 协议的视频,在第一部分有链接,一起学,淦!

    五、参考资料

    1、基于STM32的0.96寸OLED显示屏显示数据
    2、0.96寸OLED在STM32f103上实现滚动显示长字符

    展开全文
  • 本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、不同算子的图像锐化知识...

           本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、不同算子的图像锐化知识。希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生。
           【数字图像处理】一.MFC详解显示BMP格式图片
           【数字图像处理】二.MFC单文档分割窗口显示图片
           【数字图像处理】三.MFC实现图像灰度、采样和量化功能详解
           【数字图像处理】四.MFC对话框绘制灰度直方图
           【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解
           【数字图像处理】六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
            
    免费资源下载地址:
            http://download.csdn.net/detail/eastmount/8785591

     

    一. 图像增强简介

            图像增强是对图像进行处理,使其比原始图像更适合于特定的应用,它需要与实际应用相结合。对于图像的某些特征如边缘、轮廓、对比度等,图像增强是进行强调或锐化,以便于显示、观察或进一步分析与处理。图像增强的方法是因应用不同而不同的,研究内容包括:(参考课件和左飞的《数字图像处理》)

     

    二. 图像平滑

            图像平滑是一种区域增强的算法,平滑算法有邻域平均法、中指滤波、边界保持类滤波等。在图像产生、传输和复制过程中,常常会因为多方面原因而被噪声干扰或出现数据丢失,降低了图像的质量(某一像素,如果它与周围像素点相比有明显的不同,则该点被噪声所感染)。这就需要对图像进行一定的增强处理以减小这些缺陷带来的影响。

           1.简单平滑-邻域平均法
            图像简单平滑是指通过邻域简单平均对图像进行平滑处理的方法,用这种方法在一定程度上消除原始图像中的噪声、降低原始图像对比度的作用。它利用卷积运算对图像邻域的像素灰度进行平均,从而达到减小图像中噪声影响、降低图像对比度的目的。
            但邻域平均值主要缺点是在降低噪声的同时使图像变得模糊,特别在边缘和细节处,而且邻域越大,在去噪能力增强的同时模糊程度越严重。

            2.高斯平滑
           
    为了克服简单局部平均法的弊端(图像模糊),目前已提出许多保持边缘、细节的局部平滑算法。它们的出发点都集中在如何选择邻域的大小、形状和方向、参数加平均及邻域各店的权重系数等。
            图像高斯平滑也是邻域平均的思想对图像进行平滑的一种方法,在图像高斯平滑中,对图像进行平均时,不同位置的像素被赋予了不同的权重。
            在图像简单平滑中,算法利用卷积模板逐一处理图像中每个像素,这一过程可以形象地比作对原始图像的像素一一进行过滤整理,在图像处理中把邻域像素逐一处理的算法过程称为滤波器。平滑线性滤波器的工作原理是利用模板对邻域内像素灰度进行加权平均,也称为均值滤波器。
            高斯平滑与简单平滑不同,它在对邻域内像素进行平均时,给予不同位置的像素不同的权值,下图的所示的3*3和5*5领域的高斯模板。

            模板越靠近邻域中心位置,其权值越高。在图像细节进行模糊时,可以更多的保留图像总体的灰度分布特征。下图是常用的四个模板和matlab代码实现:

            代码如下:

    I1 = imread('blood1.tif');
    I=imnoise(I1,‘salt & pepper’,0.04);                %对图像加椒盐噪声
    imshow(I);
    h1= [0.1 0.1 0.1; 0.1 0.2 0.1; 0.1 0.1 0.1];        %定义4种模板
    h2=1/16.*[1 2 1;2 4 2;1 2 1];
    h3=1/8.*[1 1 1;1 0 1;1 1 1];
    h4=1/2.*[0 1/4 0;1/4 1 1/4;0 1/4 0];
    I2=filter2(h1,I);                                   %用4种模板进行滤波处理
    I3=filter2(h2,I);
    I4=filter2(h3,I);
    I5=filter2(h4,I);
    figure,imshow(I2,[])                                %显示处理结果
    figure,imshow(I3,[])
    figure,imshow(I4,[])
    figure,imshow(I5,[])

            运行效果如下图所示:

            3.中值滤波
            在使用邻域平均法去噪的同时也使得边界变得模糊。而中值滤波是非线性的图像处理方法,在去噪的同时可以兼顾到边界信息的保留。
            选一个含有奇数点的窗口W,将这个窗口在图像上扫描,把窗口中所含的像素点按灰度级的升或降序排列,取位于中间的灰度值来代替该点的灰度值。

            例如选择滤波的窗口如下图,是一个一维的窗口,待处理像素的灰度取这个模板中灰度的中值,滤波过程如下:

            常用的窗口还有方形、十字形、圆形和环形。不同形状的窗口产生不同的滤波效果,方形和圆形窗口适合外轮廓线较长的物体图像,而十字形窗口对有尖顶角状的图像效果好。

            中值滤波对于消除孤立点和线段的干扰十分有用,尤其是对于二进噪声,但对消除高斯噪声的影响效果不佳。对于一些细节较多的复杂图像,可以多次使用不同的中值滤波。matlab实现参考:http://blog.csdn.net/timidsmile/article/details/6904381

            4.边界保持类滤波
            K近邻均值滤波器(KNNF)是指在m*m的窗口中,属于同一集合类的像素,它们的灰度值将高度相关。被处理的像素(对应于窗口中心的像素)可以用窗口内与中心像素灰度最接近的k个近邻像素的平均灰度来替代。步骤如下:
            (1).作一个m*m的作用模板
            (2).在其中选择K个与待处理像素的灰度差为最小的像素
            (3).用这K个像素的灰度均值替换掉原来的值

            在K近旁均值滤波器(KNNMF)中,不选K个邻近像素的平均灰度来替代,而选K个邻近像素的中值灰度来替代,上图中2,3,3中选择3即可。
            下面介绍具体MFC VC++6.0代码实现过程。

     

    三. 图像平滑代码实现

            第一步:在资源视图的Menu中添加子菜单“图像增强”,然后添加“图像平滑”四个选项如下图所示:

            第二步:打开类向导,在ImageProcessingView类中添加相应的四个实现函数:

            第三步:就是具体的平滑实现函数。
            1.普通平滑 模板一
            该算法采用的模板如下:

            代码如下:

    /**************************************************
      第九章--图像增强    
      图像平滑 普通平滑 模板
     
    float H1[3][3]={{1.0/10,1.0/10,1.0/10}, //模板一:系数1/10
    			   {1.0/10,2.0/10,1.0/10},
    			   {1.0/10,1.0/10,1.0/10}};
    		
    float H2[3][3]={{1.0/16,2.0/16,1.0/16}, //模板二:系数1/16
    			   {2.0/16,4.0/16,2.0/16},
    			   {1.0/16,2.0/16,1.0/16}};
    
    float H3[3][3]={{1.0/8,1.0/8,1.0/8},    //模板三:系数1/8,此种情况为把点转为空心矩形
    			   {1.0/8,0.0/8,1.0/8},
    			   {1.0/8,1.0/8,1.0/8}};
    
    float H4[3][3]={{0.0,1.0/8,0.0},        //模板四:系数乘数据后的矩阵
    			   {1.0/8,1.0/2,1.0/8},
    			   {0.0,1.0/8,0.0}};
    
    /**************************************************/
    
    
    void CImageProcessingView::OnTxzqPtph1() 
    {
    	if(numPicture==0) {
    		AfxMessageBox("载入图片后才能图像增强(平滑)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(平滑)!选取的模板为:普通平滑 模板一",MB_OK,0);
    
    	/******************************************************************/
    	/* 图想平滑的算法:                                               
    	/*   1.定义常用的四个模板,它们的维数均为3,矩阵的个数均为9个数据   
    	/*   2.它的思想是把一个点分散到这周围的9个点上,这样使图像更模糊   
    	/*   3.通过卷积计算围绕该点的矩阵像素和,计算其平均值(除9)赋值给点 
    	/*   4.模块不同,处理后的图像也各不相同                           
    	/******************************************************************/
    
    	/*第一步:先定义数据模板*/
    	int HWS=3;                                //模板维数:此四个模板均为3维的
    	float H1[3][3]={{1.0/10,1.0/10,1.0/10},   //模板一:系数1/10
    					{1.0/10,2.0/10,1.0/10},
    					{1.0/10,1.0/10,1.0/10}};
    	
    	//打开临时的图片
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	//new和delete有效的进行动态内存的分配和释放
        unsigned char *ImageSize;        
        ImageSize = new unsigned char[m_nImage];    
    	float red,green,blue;
    	int X,Y;               //一维坐标转换为二维坐标
    	int TR,TG,TB;          //记录红绿蓝坐标位置
    
    	//图像增强:平滑 它要获取源图像周围9个点的矩阵乘以模板9个点的矩阵,故一维图像转二维
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		//原图:一维矩阵转换为二维矩阵
    		X=(i/3)%m_nWidth;    //图像在X列
    		Y=(i/3)/m_nWidth;    //图像在Y行
    
    		//赋值为黑色,相当于清零
    		red=green=blue=0;
    
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )      //防止越界
    				{			
    					//模板一 进行模板平均,把该点像素分散到四周
    					TR=j*m_nWidth*3+k*3;	
    					red+=H1[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H1[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H1[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		ImageSize[i]=(unsigned char)(red);
    		ImageSize[i+1]=(unsigned char)(green);
    		ImageSize[i+2]=(unsigned char)(blue);
    	}
    		
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;
    	Invalidate();
    }

            运行效果如图所示,图像平滑模糊了,但效果不是很好。

            其中实现的具体原理如下:
            首先将图像像素矩阵转换为(X,Y)的二维矩阵进行操作,同时获取(X,Y)坐标为中心的3*3矩阵,再通过它与3*3模板进行像素平均操作,就是两个3*3矩阵互乘。需要注意的是矩阵一个格子是RGB三字节(24位BMP),同时获取该中心点位置时,通过两层循环for(k=n-1;k<=n+1;k++)实现获取矩阵中九个点的像素。最后对该点(X,Y)的RGB进行赋值操作即可。


           2.普通平滑 模板二
            该算法采用的模板如下:

            代码如下:

    void CImageProcessingView::OnTxzqPtph2() 
    {
    	if(numPicture==0) {
    		AfxMessageBox("载入图片后才能图像增强(平滑)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(平滑)!选取的模板为:普通平滑 模板二",MB_OK,0);
    
    	/*第一步:先定义数据模板*/
    	int HWS=3;
    	float H2[3][3]={{1.0/8,1.0/8,1.0/8},    //模板三:系数1/8 此种情况为把点转为空心矩形
    					{1.0/8,0.0/8,1.0/8},
    					{1.0/8,1.0/8,1.0/8}};
    	
    	//打开临时的图片
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	
    	//重点:图像的每行像素都必须是4的倍数:1*1的图像为 r g b 00H   
    	int num;            //记录每行多余的图像素数个数  
    	int sfSize;         //补齐后的图像大小  
        if(m_nWidth*3%4!=0) {  
            num=(4-m_nWidth*3%4);  
            sfSize=(m_nWidth*3+num)*m_nHeight; //每行多number个  
        }  
        else {  
            num=0;  
            sfSize=m_nWidth*m_nHeight*3;  
        }  
      
        /*更改文件头信息 定义临时文件头结构变量*/  
        BITMAPFILEHEADER bfhsf;  
        BITMAPINFOHEADER bihsf;         
        bfhsf=bfh;  
        bihsf=bih;  
        bfhsf.bfSize=sfSize+54;  
        fwrite(&bfhsf,sizeof(BITMAPFILEHEADER),1,fpw);  
        fwrite(&bihsf,sizeof(BITMAPINFOHEADER),1,fpw);  
        fread(m_pImage,m_nImage,1,fpo);  
    
    	//new和delete有效的进行动态内存的分配和释放
        unsigned char *ImageSize;        
        ImageSize = new unsigned char[sfSize];    
    	float red,green,blue;
    	int X,Y;               //一维坐标转换为二维坐标
    	int TR,TG,TB;          //记录红绿蓝坐标位置  
        int countWidth=0;      //记录每行的像素个数,满行时变回0  
    	int place=0;           //建立临时坐标 记录起始坐标(0,0)平移过来的位置 
    
    	//图像增强 平滑
    	for(int i=0; i<m_nImage; )
    	{
    		//原图一维矩阵转换为二维矩阵
    		X=(i/3)%m_nWidth;    //图像在X列
    		Y=(i/3)/m_nWidth;    //图像在Y行
    
    		//赋值为黑色,相当于清零
    		red=green=blue=0;
    
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )      //防止越界
    				{			
    					//模板二 进行模板平均,把该点像素分散到四周
    					TR=j*m_nWidth*3+k*3;	
    					red+=H2[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H2[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H2[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		//通过变量place赋值变换后的图像 i始终指向原图3的倍数 为了补0而添加place变量
    		ImageSize[place]=(unsigned char)(red);
    		i++; place++;
    		ImageSize[place]=(unsigned char)(green);
    		i++; place++;
    		ImageSize[place]=(unsigned char)(blue);
    		i++; place++;
    		countWidth=countWidth+3;
    		
    		if(countWidth==m_nWidth*3)    
            {    
    			if(num==0)  
                {  
                    countWidth=0;    
                    place=Y*m_nWidth*3;
                }  
                else //num为补0  
                {  
                    for(int n=0;n<num;n++)  
                    {    
                        ImageSize[place]=0;  
    					place++;  
                    }  
                    countWidth=0;   
                    place=Y*(m_nWidth*3+num); //重点 添加Num  
                }  
    		} 
    	}
    		
    	fwrite(ImageSize,sfSize,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture=2;
    	level=400;
    	Invalidate();
    }

            你可能注意到了,在图像处理过程中,如果每行的字节数不是4的倍数,可能会出现斜线之类的处理BUG,所以需要手动补0筹齐4的倍数,代码中补0后运行效果如下图所示,我也一直没找到原因,可能是思想和深度还没有达到,以后有机会在解决吧!同时后面的算法都不准备再进行补0处理,主要讲述算法的思想!

             3.高斯平滑
             采用的模板如下:

            代码如下图所示:

    //高斯平滑
    void CImageProcessingView::OnTxzqGsph() 
    {
    	if(numPicture==0) {
    		AfxMessageBox("载入图片后才能图像增强(平滑)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(平滑)!选取的模板为:高斯平滑",MB_OK,0);
    
    	/*第一步:先定义数据模板*/
    	int HWS=3;                                //模板维数为3维
    	float H[3][3]={{1.0/16,2.0/16,1.0/16},    //高斯模板 系数1/16
    				   {2.0/16,4.0/16,2.0/16},
    				   {1.0/16,2.0/16,1.0/16}};
    	
    	//打开临时的图片
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	//new和delete有效的进行动态内存的分配和释放
        unsigned char *ImageSize;        
        ImageSize = new unsigned char[m_nImage];    
    	float red,green,blue;
    	int X,Y;               //一维坐标转换为二维坐标
    	int TR,TG,TB;          //记录红绿蓝坐标位置
    
    	//图像增强:平滑 
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		//原图:一维矩阵转换为二维矩阵
    		X=(i/3)%m_nWidth;    //图像在X列
    		Y=(i/3)/m_nWidth;    //图像在Y行
    
    		//赋值为黑色,相当于清零
    		red=green=blue=0;
    
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )      //防止越界
    				{			
    					//模板二 进行模板平均,把该点像素分散到四周
    					TR=j*m_nWidth*3+k*3;	
    					red+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		ImageSize[i]=(unsigned char)(red);
    		ImageSize[i+1]=(unsigned char)(green);
    		ImageSize[i+2]=(unsigned char)(blue);
    	}
    		
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;
    	Invalidate();
    }

            运行效果如下图所示:

            4.中值滤波
            中值滤波我的理解是:它不但可以去除孤点噪声,而且可以保持图像的边缘特性,不会产生显著的模糊;它的方法是把局部区域的像素按灰度等级进行排序,再取该邻域中灰度的中值作为当前像素的灰度值。其步骤如下:
            (1).将滤波模板(含若干个点的滑动窗口)在图像中漫游,并将模板中心与图像中的某个像素位置重合;
            (2).读取模板中各对应像素的灰度值;
            (3).将这些灰度值从小到大排序;
            (4).取这一列数据的中间数据,将其赋值给对应模板中心位置的像素。

            我采用的是3*3的模本,取矩阵中间位置像素替代原像素。代码如下:

    //中值滤波
    void CImageProcessingView::OnTxzqZzlb() 
    {
    	if(numPicture==0) {
    		AfxMessageBox("载入图片后才能图像增强(平滑)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(平滑)!选取的模板为:中值滤波",MB_OK,0);
    
    	//打开临时的图片
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	//new和delete有效的进行动态内存的分配和释放
        unsigned char *ImageSize;        
        ImageSize = new unsigned char[m_nImage];    
    	int X,Y;               //一维坐标转换为二维坐标
    	int TR,TG,TB;          //记录红绿蓝坐标位置
    
    	//选取它为中心的周围9个点像素(注意一个点为RGB)
    	int H[9]={0,0,0,0,0,0,0,0,0};    
    	int HWS=3;             //维数为三维
    
    	//图像增强:平滑 它要获取源图像周围9个点的矩阵乘以模板9个点的矩阵,故一维图像转二维
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		//原图:一维矩阵转换为二维矩阵
    		X=(i/3)%m_nWidth;    //图像在X列
    		Y=(i/3)/m_nWidth;    //图像在Y行
    		
    		//第一行 第一列 最后一行 最后一列 直接复制
    		if(X==0 || Y==0 || X==m_nWidth*3 || Y==m_nHeight) 
    		{
    			if(i+2>m_nImage) break;
    			ImageSize[i] = m_pImage[i];
    			ImageSize[i+1] = m_pImage[i+1];
    			ImageSize[i+2] = m_pImage[i+2];
    			continue;
    		}
    
    		//对图像进行像素求和并取平均值 HWS维数
    		int num=0;
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )      //防止越界
    				{			
    					//获取当前位置Red像素 k一次增加RGB三个像素 R=G=B
    					TR = j*m_nWidth*3+k*3;	
    					H[num] = m_pImage[TR];
    					num++;
    				}
    			}
    		}
    		//排序获取中间值
    		int temp=0;
    		for(int x=0;x<9;x++)
    		{
    			for(int y=x;y<9;y++)
    			{
    				if(H[x]>=H[y])
    				{
    					temp=H[x];
    					H[x]=H[y];
    					H[y]=temp;
    				}
    			}
    		}
    		//CString str;
    		//str.Format("矩阵:%d %d %d, %d %d %d, %d %d %d",H[0],H[1],H[2],H[3],H[4],H[5],H[6],H[7],H[8]);
    		//AfxMessageBox(str);
    
    		//对新图像赋值 灰度图像RGB相同
    		ImageSize[i]=H[4];
    		ImageSize[i+1]=H[4];
    		ImageSize[i+2]=H[4];
    	}
    		
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;
    	Invalidate();
    }

            运行效果如下图所示:

            PS:这部分总算讲述完成,算法都是根据自己的理解用底层代码实现的,而不是向其它的通过调用GDI+库实现。可能存在因为理解不够或其它的错误,欢迎提出修改~
            推荐资料:
            图像平滑处理——OpenCV         数字图像处理学习笔记——图像平滑锐化 
            中值滤波    

     

    四. 图像锐化

           有时还需要加强图像中景物的边缘和轮廓,边缘和轮廓通常位于图像中灰度突出的地方,因而可以直观的想到用灰度的差分对边缘和轮廓进行提取,通常可以通过梯度算子进行提取。图像锐化的目的是提高图像的对比度,从而使图像更清晰,通过提高邻域内像素的灰度差来提高图像的对比度。
           下面介绍图像锐化的几种算子及效果。
            1.拉普拉斯算子(Laplacian)
            拉普拉斯算子是图像邻域内像素灰度差分计算的基础,通过二阶微分推导出的一种图像邻域增强算法。它的基本思想是当邻域的中心像素灰度低于它所在邻域内的其他像素的平均灰度时,此中心像素的灰度应该被进一步降低;当高于时进一步提高中心像素的灰度,从而实现图像锐化处理。
            在算法实现过程中,通过对邻域中心像素的四方向或八方向求梯度,并将梯度和相加来判断中心像素灰度与邻域内其他像素灰度的关系,并用梯度运算的结果对像素灰度进行调整。
            一个连续的二元函数f(x,y),其拉普拉斯运算定义为:

            对于数字图像,拉普拉斯算子可以简化为:

            也可以表示为卷积的形式:

            其中K=1,I=1时H(r,s)取下式,四方向模板:

            通过模板可以发现,当邻域内像素灰度相同时,模板的卷积运算结果为0;当中心像素灰度高于邻域内其他像素的平均灰度时,模板的卷积运算结果为正数;当中心像素的灰度低于邻域内其他像素的平均灰度时,模板的卷积为负数。对卷积运算的结果用适当的衰弱因子处理并加在原中心像素上,就可以实现图像的锐化处理。
            其中实现过程步骤如下:
            添加子菜单和类向导添加实现函数

            代码如下:

    /*****************************************/
    /* 图像锐化:我在menu中创建5个子的menu    */
    /* 防止出现平滑错误,一次只调用一个下拉单 */
    /* ID_RH_Laplacian Laplacian拉普拉斯算子 */
    /* ID_RH_Sobel Sobel算子                 */
    /* ID_RH_Prewitt Prewitt算子             */
    /* ID_RH_Isotropic Isotropic算子         */
    /* ID_RH_GTMB 高通模板H2                 */
    /*****************************************/
    
    void CImageProcessingView::OnRHLaplacian() 
    {
    	if(numPicture==0) 
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(锐化):采用拉普拉斯(Laplacian)算子!");
    
    	//模板维数:此四个模板均为3维的
    	int HWS=3;  
    	int H[3][3]={{0,-1,0},    //模板为拉普拉斯算子(中心为4的Laplacian)
    				{-1,4,-1},
    				{0,-1,0}};
    
    	//读写文件
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	//new和delete有效的进行动态内存的分配和释放
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	int red,green,blue;
    	int X,Y;       //一维坐标转换为二维坐标
    	int TR,TG,TB;  //记录红绿蓝坐标位置
    	
    	//图像增强 锐化
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		red=green=blue=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					red+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		if(red>=0 && red<256) ImageSize[i]=red;
    		else if(red<0) ImageSize[i]=0;      //ImageSize[i]=-red;
    		else ImageSize[i]=0;
    		
    		if(green>=0 && green<256) ImageSize[i+1]=green;
    		else if(green<0) ImageSize[i+1]=0;  //ImageSize[i+1]=-green;
    		else ImageSize[i+1]=0;
    		
    		if(blue>=0 && blue<256) ImageSize[i+2]=blue;
    		else if(blue<0) ImageSize[i+2]=0;   //ImageSize[i+2]=-blue;
    		else ImageSize[i+2]=0;
    	}
    	
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();
    }

            运行效果如下图所示:


            2.高通滤波
            常用的高通模板如下所示,其中H2有的书又称为拉普拉斯八方向的锐化模板。

            选取H2模板,代码如下所示:

    //高通模板
    void CImageProcessingView::OnRhGtmb() 
    {
    	if(numPicture==0)
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(锐化):采用高通模板!");
    
    	int HWS=3;                                
    	int H[3][3]={{-1,-1,-1},    
    				{-1,8,-1},
    				{-1,-1,-1}};
    
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	int red,green,blue;
    	int X,Y;       
    	int TR,TG,TB; 
    	
    	//图像增强 锐化
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		red=green=blue=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					red+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    				}
    			}
    		}
    		
    		//对新图像赋值
    		if(red>=0 && red<256) ImageSize[i]=red;
    		else if(red<0) ImageSize[i]=0;      //ImageSize[i]=-red;
    		else ImageSize[i]=0;
    		
    		if(green>=0 && green<256) ImageSize[i+1]=green;
    		else if(green<0) ImageSize[i+1]=0;  //ImageSize[i+1]=-green;
    		else ImageSize[i+1]=0;
    		
    		if(blue>=0 && blue<256) ImageSize[i+2]=blue;
    		else if(blue<0) ImageSize[i+2]=0;   //ImageSize[i+2]=-blue;
    		else ImageSize[i+2]=0;
    	}
    	
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();	
    }

            运行效果如下图所示,该效果相对较好:

     


           3.Sobel算子

            代码如下所示,需要注意X和Y两个方向的模板处理:

    //Sobel算子采用PPT上的d(x)d(y)模板
    void CImageProcessingView::OnRHSobel() 
    {
    	if(numPicture==0)
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(锐化):采用Sobel算子!");
    
    	int HWS=3;                                
    	//模板为Sobel算子
    	int HX[3][3]={{1,0,-1},{2,0,-2},{1,0,-1}};
    	int HY[3][3]={{-1,-2,-1},{0,0,0},{1,2,1}};
    
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);	
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	int redX,greenX,blueX;
    	int redY,greenY,blueY;
    	int X,Y;       
    	int TR,TG,TB;  
    	
    	//图像增强 锐化
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		redX=greenX=blueX=0;
    		redY=greenY=blueY=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					redX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					redY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					greenX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					greenY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blueX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    					blueY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    				}
    			}
    		}
    		//s=(d(x)*d(x)+d(y)*d(y))开根号
    		int R,G,B;
    		R=(int)(sqrt(redX*redX*1.0+redY*redY*1.0));
    		G=(int)(sqrt(greenX*greenX*1.0+greenY*greenY*1.0));
    		B=(int)(sqrt(blueX*blueX*1.0+blueY*blueY*1.0));
    
    		if(redX<0 && redY<0) ImageSize[i]=0;
    		else if(R>255) ImageSize[i]=255;
    		else ImageSize[i]=R;
    		
    		if(greenX<0 && greenY<0) ImageSize[i+1]=0;
    		else if(G>255) ImageSize[i+1]=255;
    		else ImageSize[i+1]=G;
    
    		if(blueX<0 && blueY<0) ImageSize[i+2]=0;
    		else if(B>255) ImageSize[i+2]=255;
    		else ImageSize[i+2]=B;
    	}
    	
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();
    }

            运行效果如下图所示:

            如果采用Sobel边缘细化,建议二值化(0和255阈值化)处理后再锐化,彩色图建议先灰度处理再进行其他处理。


          4.Isotropic算子
     

            代码实现如下:

    //Isotropic算子采用PPT上的d(x)模板 d(y)
    void CImageProcessingView::OnRHIsotropic() 
    {
    	if(numPicture==0)
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    
    	AfxMessageBox("图像增强(锐化):采用Isotropic算子!");
    
    	int HWS=3;                               
    	//模板为Isotropic算子
    	float HX[3][3]={{1,0,-1},
    					{sqrt(2.0),0,-sqrt(2.0)}, 
    					{1,0,-1} };
    	float HY[3][3]={{-1,-sqrt(2.0),-1},
    					{0,0,0}, 
    					{1,sqrt(2.0),1} };
    
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	float redX,greenX,blueX;
    	float redY,greenY,blueY;
    	int X,Y;      
    	int TR,TG,TB;  
    	
    	//图像增强
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		redX=greenX=blueX=0;
    		redY=greenY=blueY=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					redX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					redY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					greenX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					greenY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blueX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    					blueY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值 s=(d(x)*d(x)+d(y)*d(y))开根号
    		int R,G,B;
    		R=(int)(sqrt(redX*redX*1.0+redY*redY*1.0));
    		G=(int)(sqrt(greenX*greenX*1.0+greenY*greenY*1.0));
    		B=(int)(sqrt(blueX*blueX*1.0+blueY*blueY*1.0));
    
    		if(redX<0 && redY<0) ImageSize[i]=0;
    		else if(R>255) ImageSize[i]=255;
    		else ImageSize[i]=R;
    		
    		if(greenX<0 && greenY<0) ImageSize[i+1]=0;
    		else if(G>255) ImageSize[i+1]=255;
    		else ImageSize[i+1]=G;
    
    		if(blueX<0 && blueY<0) ImageSize[i+2]=0;
    		else if(B>255) ImageSize[i+2]=255;
    		else ImageSize[i+2]=B;
    	}
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();
    }

            运行效果如下图所示,效果与上面的Sobel类似:


           5.Prewitt算子

            代码如下图所示:

    //Prewitt算子采用PPT上的d(x)模板,不是d(y)
    void CImageProcessingView::OnRHPrewitt() 
    {
    	
    	if(numPicture==0)
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(锐化):采用Prewitt算子!");
    
    	int HWS=3;                               
    	int H[3][3]={{1,0,-1},    //模板为Prewitt算子
    				{1,0,-1},
    				{1,0,-1}};
    
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	int red,green,blue;
    	int X,Y;      
    	int TR,TG,TB; 
    	
    	//图像增强:平滑
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		red=green=blue=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					red+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		if(red>=0 && red<256) ImageSize[i]=red;
    		else if(red<0) ImageSize[i]=0;      //ImageSize[i]=-red;
    		else ImageSize[i]=0;
    		
    		if(green>=0 && green<256) ImageSize[i+1]=green;
    		else if(green<0) ImageSize[i+1]=0;  //ImageSize[i+1]=-green;
    		else ImageSize[i+1]=0;
    		
    		if(blue>=0 && blue<256) ImageSize[i+2]=blue;
    		else if(blue<0) ImageSize[i+2]=0;   //ImageSize[i+2]=-blue;
    		else ImageSize[i+2]=0;	
    	}
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();
    }

            运行效果如下图所示,只选取了X分量:

            最后还是希望文章对你有所帮助,如果文章有不足或错误之处,请海涵。自己给自己点个赞,挺不容易的,但还会继续写完~同时后面的图像处理准备研究些感兴趣的东西,而不是这样的长篇大论了,例如怎样实现验证码提取、如何实现图像恢复、DICOM图像等知识吧!

          (By:Eastmount 2015-06-08 下午6点   http://blog.csdn.net/eastmount/

    展开全文
  • PS延迟显示的解决方法

    千次阅读 2013-05-18 08:42:39
    用了Photoshop这么久,还没遇到过这个问题... 今天换了台机子就遇上了...在网上查了查 很简单的方法: 编辑--->首选项--->文字--->字体预览大小。将“字体预览大小”勾选项去除就OK了 然后重启Photoshop
    用了Photoshop这么久,还没遇到过这个问题... 今天换了台机子就遇上了...在网上查了查 很简单的方法: 
    
    编辑--->首选项--->文字--->字体预览大小。将“字体预览大小”勾选项去除就OK了 然后重启Photoshop
    展开全文
  • Nginx 的平滑升级 平滑升级概述 Nginx 平滑升级原因 随着Nginx的广泛应用,Nginx的版本迭代也来时加速模式,线上业务不能停,因此Nginx的升级就需要平滑升级。 Nginx平滑升级原理 Nginx平滑升级操作 Nginx 错误...
  • PS讲义

    千次阅读 多人点赞 2013-01-26 21:38:42
    疯狂十天PS公开课课堂笔记分享   第一天: 界面构成   1 菜单栏 2 工具箱 3 工具属性栏 4 悬浮面板 5 画布     ctrl + N 新建对话框 (针对画布进行设置)   打开对话框: ctrl + O (字母)   ...
  • 本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、不同算子的图像锐化知识...
  • 2019独角兽企业重金招聘Python工程师标准>>> 在工作中所做的web页面使用电脑,手机和平板,...然后再缩小,这样边缘比较平滑 转载于:https://my.oschina.net/u/2612473/blog/628549
  • 实验三:图像空间域平滑 实验目的  理解 图像空间域平滑的目的和意义  了解图像空间域平滑的各种方法及优缺点;  掌握图像空间域的邻域运算方法;  编程实现图像局部平均法、空间低通率波法、中值滤波法对...
  • ps笔记

    2015-09-09 00:15:37
    ## Ps工具快捷键 1. shift 画正园和正方形 2. alt 图形从坐标向四周扩散 3. shift和Alt 正方形或圆形向坐标四周扩散 4. 平滑 正角→圆角 5. ctrl+D 取消选区 6. ctrl+r 显示/隐藏标尺线 7. ctrl+z 返回上...
  • 本篇文章主要讲解Python调用OpenCV实现图像平滑,包括四个算法:均值滤波、方框滤波、高斯滤波和中值滤波。全文均是基础知识,希望对您有所帮助。知识点如下: 1.图像平滑 2.均值滤波 3.方框滤波 4.高斯滤波 5.中值...
  • PS快捷键

    千次阅读 2018-07-30 10:30:32
    显示最后一次显示的“预置”对话框 【Alt】+【Ctrl】+【K】 设置“常规”选项(在预置对话框中) 【Ctrl】+【1】 设置“存储文件”(在预置对话框中) 【Ctrl】+【2】 设置“显示和光标”(在预置对话框中) ...
  • PS,PS

    千次阅读 多人点赞 2013-02-09 15:20:46
     显示最后一次显示的“预置”对话框 :【Alt】+【Ctrl】+【K】  设置“常规”选项(在预置对话框中): 【Ctrl】+【1】  设置“存储文件”(在预置对话框中) :【Ctrl】+【2】  设置“显示...
  • ps基础

    2019-08-11 21:58:51
    关于ps的基础知识_8.03 一,位图和矢量图 1.位图 ①放大后图片会变虚 ②由像素组成(最低72像素,若像素太大容易造成电脑卡顿) ③图的质量由分辨率决定 ④一般电脑显示图片用位图 2.矢量图 ①放大...
  • ps

    2010-08-06 21:40:06
    老师教了我们二年的PS 全部在这里 照片名称:调出照片柔和的蓝×××-简单方法, 1、打开原图素材,按Ctrl + J把背景图层复制一层,点通道面板,选择蓝色通道,图像 > 应用图像,图层为背景,混合为正片叠底...
  • Apache平滑加载配置文件 Linux

    千次阅读 2018-12-06 10:57:40
    ps aux|grep http 此时会有显示文件路径 文件路径path -k graceful
  • 同时它还能区分软边界和硬边界并做相应的处理使最终的边缘和色彩过渡更加平滑。 安装方法: 解包后将整个文件夹复制粘贴到Photoshop程序目录下的“Plug-Ins”夹中,然后将“sn.reg”导入注册表完成注册;打开PS,...
  • PS也是一部非常经典的主机,也有DQ系列的不少作品,包括复刻的DQ4以及DQ7等。下面是学习啦小编收集的关于电脑ps模拟器的安装方法,希望对你有所帮助。电脑ps模拟器的安装方法ePSXe先要安装,安装好模拟器后打开。(1)...
  • 平滑重启是指能让我们的程序在重启的过程不中断服务,新老进程无缝衔接,实现零停机时间(Zero-Downtime)部署; 平滑重启是建立在优雅退出的基础之上的,之前一篇文章介绍了相关实现:Golang中使用Shutdown特性对http...
  • PS抠图一

    2020-07-24 05:08:18
    PS抠图: 1、通道选取色系选取 2、魔术棒选取同色系,补充扣取目标的边界 3、用蒙版微调 4、在选区作用下,复制图层 5、给原图加上图层蒙版 6、载入4扣出来的图的选取,给原图上的蒙版显示待扣区域 7、在图层...
  • 几种网格平滑算法的实现

    万次阅读 2016-05-17 01:16:20
    网格平滑 网格平滑属于数字几何处理领域的问题,计算机图形学和计算机辅助设计中,用多边形网格可以表示复杂的三维实体。随着三维扫描和曲面重建技术的发展,得到这些实体表面的多边形网格表示已经不是难事,但所...
  • 贪吃蛇平滑移动 初始化蛇头和蛇身 调整蛇头方向 贪吃蛇移动 蛇头和蛇身的节点顺序 ...在本教程中我们重点来学习下如何让贪吃蛇能够平滑移动。...该项目刚开始的资源管理器内容显示如下: Head.j...
  • ps学习>0627

    2019-07-01 21:41:32
    PS入门教程——新手过招>(https://www.imooc.com/learn/139) 一. 学习<PS入门教程——新手过招>2-6 PS之螺旋结构 注意两个环从分开到串在一起的方法 注意五环的画法 二. 学习<PS入门教程——新手过招&...
  • ps 常用快捷键

    2019-07-30 14:53:57
    ps 常用快捷键 快捷键 作用 ctrl+n 新建图形文件 ctrl+shift+n 新建图层 ctrl+o 打开图片 ctrl+w 关闭当前图像 ctrl+s 保存文件 ctrl+z 撤销还原 ctrl+alt+z 多步还原 ctrl+p 打印 tab 隐藏...
  • PS快捷键大全

    2019-09-30 11:48:23
    PS:按Shift+工具组快捷键能在工具组之间循环切换 功能名称 快捷键 矩形选框、椭圆选选框 M 移动工具 V 套索工具组 L 魔棒工具 W 裁切工具 C 切片工具组 K 修复画笔工具组 J 画笔工具组 B 仿制图章工具组 S 历史记录...
  • ,应用新的模块,最简单的方式是停下来,然后开启新的Nginx服务,那么给我们的用户体验是非常差的,会导致用户在一段时间内无法访问我们的服务器为了解决这个问题,Nginx提供了平滑升级的方案。   &...
  • PS技巧

    2017-08-24 15:00:57
    平滑 设置取样半径 ctrl+shift+i 反选 delete 删除 图片模糊 打开图片 滤镜-&gt;模糊-&gt;场景模糊 点白圈调整,也可于右上角输入像素调整 调整完成,点击确定 图片添加半透明...
  • ps -ef|grep nginx 之后显示注意带有master后面 root 1734 1 0 Oct28 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 那么/usr/local/nginx/con...
  • ps快捷键使用

    2019-02-04 18:04:29
    1.蒙版的黑色部分不显示,白色部分显示 2.渐变工具按住shift拉出垂直渐变线 3.生成选区:ctrl+enter 4.图层复制:ctrl+J 5.抓手工具:空白格+鼠标 6.钢笔选区一定要是“路径”,而不是“图形” 7. 8.字...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,295
精华内容 3,718
关键字:

ps显示平滑