文档章节

访问图像像素信息方式的优化

abcijkxyz
 abcijkxyz
发布于 2016/11/22 16:41
字数 1217
阅读 7
收藏 0

   如果你做图像处理有一定的经验,并且实战过N次,那么你一定知道代码优化对这个行业是多么的重要。今天,我们首先简单谈谈访问图像像素技术的优化。

     首先,我们后面的优化都要基于这个前提:我们是以一维数组的方式来访问图像的数据的,且:

     1、这个一维数组的数组名字为:ImageData

     2、数组的大小为Stride*Height。其中Stride表示图像的一个扫描行占用的字节数,这个数字必须是4的倍数。Height为图像的高度。

     3、数组的类型为byte(unsigned Char?)。

     4、图像的宽度为Width,每个像素占用的字节数用BytePerPixel变量表示,24位图像该变量的值为3,32位图像该变量的值为4.

     首先我们看看如何访问24或32位图像的像素值。比如要获取第X行第Y列(以0为起点)像素的绿色分量,则应该用ImageData(Stride*Y+X*BytePerPixel+1)表示,红色分量则为ImageData(Stride*Y+X*BytePerPixel+2)。好,这样我们就可以写个简单的反色的代码了。

1      For Y =  0  To Height -  1
2          For X =  0  To Width -  1
3             ImageData(Y * Stride + X * BytePerPixel) =  255 - ImageData(Y * Stride + X * BytePerPixel)            ' Blue分量
4             ImageData(Y * Stride + X * BytePerPixel +  1) =  255 - ImageData(Y * Stride + X * BytePerPixel +  1)    ' Green分量
5             ImageData(Y * Stride + X * BytePerPixel +  2) =  255 - ImageData(Y * Stride + X * BytePerPixel +  2)    ' Red分量
6          Next
7      Next

      注意到反色一般是不处理Alpha通道的。

     上述代码思路清晰、描述准确,每行的意义明显,是作为新手最好的熟悉图像内存摆布的表达方式,作为考试题的话肯定是可以打100分的。但是如果是作为项目赚钱的话,顶多是个60分吧。

      首先,我们观察,在每行中出来了大量的重复计算:Y * Stride + X * BytePerPixel,我们应该只要计算一次他就可以,好的,接着改进:

1  For Y =  0  To Height -  1
2      For X =  0  To Width -  1
3         Speed = Y * Stride + X * BytePerPixel
4         ImageData(Speed) =  255 - ImageData(Speed)            ' Blue分量
5         ImageData(Speed +  1) =  255 - ImageData(Speed +  1)    ' Green分量
6         ImageData(Speed +  2) =  255 - ImageData(Speed +  2)    ' Red分量
7      Next
8  Next

     计算速度会有大幅度的提升,好可以拿个80分了。

     还有没有改良的空间呢,注意观察在X层的循环中, Y * Stride始终是一个定量,而我们每次都重复计算了他,有必要把他提到外层的循环中,同时我们还想对X * BytePerPixel做点手脚,尽量减少乘法,毕竟乘法的CPU周期比加法要多一些。好,看我们最后的改进版本:

1  For Y =  0  To Height -  1
2      Speed = Y * Stride
3       For X =  0  To Width -  1
4          ImageData(Speed) =  255 - ImageData(Speed)            ' Blue分量
5          ImageData(Speed +  1) =  255 - ImageData(Speed +  1)    ' Green分量
6          ImageData(Speed +  2) =  255 - ImageData(Speed +  2)    ' Red分量
7          Speed = Speed + BytePerPixel                         ' 跳到下一个像素
8       Next
9   Next

      也有人喜欢用下面的方式:

 1     LineAddBytes = Stride - Width * BytePerPixel
 2      For Y =  0  To Height -  1
 3          For X =  0  To Width -  1
 4             ImageData(Speed) =  255 - ImageData(Speed)            ' Blue分量
 5             ImageData(Speed +  1) =  255 - ImageData(Speed +  1)    ' Green分量
 6             ImageData(Speed +  2) =  255 - ImageData(Speed +  2)    ' Red分量
 7             Speed = Speed + BytePerPixel                         ' 跳到下一个像素
 8          Next
 9         Speed = Speed + LineAddBytes                             ' 补齐扫描行最后的数据
10      Next

      第二种表达方式更加突出了扫描行的大小并不一定等于图像宽度*每像素的占用的字节数,所以在每次扫描一行之后要注意补齐未处理的那部分。这也是很多图像处理初学者在处理图像时可能会遇到处理后的图像效果沿对角线错位的原因。包括我们很多的专业的数字图像处理书,比如我常看的朗锐的那本VC图像处理教程,都没有很注意这个问题。而那些教材一般所测试用的图像是传说中的lena图像,这个图像大小似乎是256*256,由于宽度正好是4的倍数,LineAddBytes这个变量为0,因此这个问题就被隐藏起来了。

     我个人更习惯于使用第一种表达方式。

     对于使用C或C++编程的朋友,上述代码还有可以优化的地方,++运算符能替代某些算式的。

     有两个问题提醒大家注意:

     1、图像处理算法中在正常情况下都是先按行处理,在进行列方向递增,这样做对于代码的优化有很大的好处,因为图像在内存的数据摆布也是一行接着一行的。

     2、两个方向的循环注意一般都是从下标0开始的,一般不建议从1开始。

 

 

本文转载自:http://www.cnblogs.com/Imageshop/archive/2011/11/12/2246362.html

abcijkxyz
粉丝 63
博文 6196
码字总数 1876
作品 0
深圳
项目经理
私信 提问
Correcting Over-Exposure in Photographs

论文:Correcting Over-Exposure in Photographs 本论文主要讨论过曝光校正算法。所谓过曝光,示例如下所示: 过曝光图片校正示例 图片中女孩脸部有部分过亮(用蓝色画出部分)。为了达到曝光...

Mordekaiser
2017/07/20
0
0
人工智能也要进击二次元界了:深度学习简化素描 So Easy!

雷锋网(公众号:雷锋网)按:本文为 AI 研习社编译的技术博客,原标题 Simplifying Rough Sketches using Deep Learning,作者为 Ashish Sinha。 翻译 | 周静 整理 | 凡江 素描是表达艺术思想...

雷锋字幕组
2018/07/30
0
0
滤波器——BoxBlur均值滤波及其快速实现

动机:卷积核、滤波器、卷积、相关 在数字图像处理的语境里,图像一般是二维或三维的矩阵,卷积核(kernel)和滤波器(filter)通常指代同一事物,即对图像进行卷积或相关操作时使用的小矩阵...

Mr-Lee
2018/07/23
0
0
CVPR论文《100+ Times Faster Weighted Median Filter (WMF)》的实现和解析(附源代码)。

  四年前第一次看到《100+ Times FasterWeighted Median Filter (WMF)》一文时,因为他附带了源代码,而且还是CVPR论文,因此,当时也对代码进行了一定的整理和解读,但是当时觉得这个算法...

Imageshop
2018/11/13
0
0
[Python图像处理] 二.OpenCV+Numpy库读取与修改像素

版权声明:本文为博主原创文章,转载请注明CSDN博客源地址!共同学习,一起进步~ https://blog.csdn.net/Eastmount/article/details/82120114 该系列文章是讲解Python OpenCV图像处理知识,前...

Eastmount
2018/08/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

九、RabbitMQ的集群安装

概述 理解RabbitMQ的集群原理可能需要花点功夫,但是配置RabbitMQ的集群则非常容易。 注意 如果有防火墙,请提前开放相关端口: client端通信口5672 管理口15672 server间内部通信口25672 e...

XuePeng77
24分钟前
1
0
今天的学习

今天学到了用ci框架向数据库添加数据,代码是这样的: $picture = $this->input->post('picture');$price = $this->input->post('price');$name = $this->input->post('name');$standa......

墨冥
33分钟前
1
0
Java agentlib参数分析

Java agentlib参数分析 再用intellij idea进行远程调试的时候,具体的配置选项如下: 标红的一行显示了远程调试需要添加的虚拟机参数。这个参数到底有什么意义? 我在命令行输入java命令,输...

Mr_Tea伯奕
49分钟前
2
0
四种软件架构演进史,程序员会一种就很牛了!

如果一个软件开发人员,不了解软件架构的演进,会制约技术的选型和开发人员的生存、晋升空间。这里我列举了目前主要的四种软件架构以及他们的优缺点,希望能够帮助软件开发人员拓展知识面。 ...

我最喜欢三大框架
54分钟前
6
0
如何做高可用的架构设计?

定义目标 既然我们的目标是做到高可用,那么我们就有必要先明确清楚高可用的含义,并通过拆解目标,让目标可以被量化。按照我的理解,可以将目标按照以下三条进行拆解: 1. 保持业务高稳定性...

别打我会飞
54分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部