Visual Basic 与图像处理 ( 二 ) 6 、阈值变换 图像的阈值变换可以将一幅图像变为黑白二值图像,即按照设定的阈值,如果图像中像素点的灰度值小于该阈值,则将该像素点的灰度值设定为 0 ,在图像中显示为黑色,否则将改点的灰度值设定为 255 ,在图像中显示为白色。有时候为强化阈值后的效果,也会将阈值结果进行反相。 阈值变换的原理可以表达为如下的函数形式: 这里的 T 就是设定的阈值。 阈值变换的实现方法也比较简单,在本例示范时,增加了一个水平滚动条用于设定阈值,其余界面与灰度线性变换的类似,软件的界面如下图所示: 这里用一个 ThresholdValued 窗体级别变量作为阈值,其中阈值变换按钮对于的代码如下: Private Sub cmdThresholdTrans_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim NGrayValue As Integer ThresholdValue = Val(txtThreshold) ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ' 彩色图像的阈值变换 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b If GrayValue ThresholdValue Then NGrayValue = 0 Else NGrayValue = 255 PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub 滚动条对应的代码如下: Private Sub HScroll1_Change() txtThreshold = Str(HScroll1.Value) End Sub 当文本框失去焦点时,也自动更改阈值,对应的代码如下: Private Sub txtThreshold_LostFocus() HScroll1.Value = Val(txtThreshold) End Sub
Visual Basic 与图像处理 ( 二 ) 5 、灰度线性变换 灰度线性变换也是一种典型的点运算,原理也比较简单,就是将图像中所有像素点的灰度按照线性函数进行变换,以 D image 表示目标图像, S image 表示源图像,灰度线性变换可以理解为: D image =k*S image +b 其中 k 为线性函数的斜率, b 为线性函数在 y 轴上的截距。当 k1 时,整个图像灰度的分布区域将变大,目标图像的整体对比度增大;反之,当 k1 时,整个图像灰度的分布区域将变小,目标图像的整体对比度减小;而 k=1 时,目标图像所有像素点的灰度增大或者减小,使得图像整体变亮或者变暗,而图像的整体对比度并不发生改变。 有两种特殊情况,当 k=1 , b=0 时,目标图像与原图像;而当 k=-1 , b=255 时,目标图像的灰度正好与原图像反转,就是平时所说的反相。 对于给定的 k 值和 b 值,对图像进行灰度线性变换比较简单,软件界面与灰度化处理的程序类似,直接更改其中的几句代码即可,软件的运行界面如下: 灰度线性变换按钮对应的代码如下: Private Sub cmdLinearTrans_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim NGrayValue As Integer Dim k As Integer, t As Integer ' 改用字母 t ,避免与颜色值变量重复 ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth k = Val(txtK) t = Val(txtB) ' 彩色图像的灰度线性变换 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b NGrayValue = k * GrayValue + t If NGrayValue 255 Then NGrayValue = 255 ' 如果超过 255 ,统一设定为 255 If NGrayValue 0 Then NGrayValue = 0 ' 如果小于 0 ,统一设定为 0 PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub 特殊情况下,当 k=-1 , b=255 时,实现的是图像的反相,效果如下图所示:
Visual Basic 与图像处理 ( 二 ) 4 、基于灰度直方图的灰度特征值计算 前文介绍过直接基于图像的每个像素点计算图像的均值和方差,在得到图像的灰度直方图统计以后,还可以根据直方图统计结果进行图像均值和方差的计算,这种算法效率更高,程序运行更快,尤其对于尺寸较大的图像,这种优势更为明显。算法的本质是将灰度等级相同的像素点进行归类,一次性计算出其和值,然后来计算均值和方差。本例将这种算法与前文直接根据像素点计算的方法进行比对,软件的界面如下: 从图中可以看出,两者的结果是一致的,其中基于直方图的特征计算按钮对应的代码如下: Private Sub cmdCalFeatureBaseHist_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Hist(0 To 255) As Long Dim SumValue As Long Dim MeanValue As Single Dim StdValue As Single ' 直方图统计 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i ' 图像均值计算 For i = 1 To 255 ' 计算和值是,灰度等级为 0 的直接省略 SumValue = SumValue + Hist(i) * i Next i MeanValue = SumValue / SourceImHeight / SourceImWidth MeanValue = Format(MeanValue, "0.00") ' 保留两位小数 txtNewMean = Str(MeanValue) ' 图像标准差计算 SumValue = 0 For i = 0 To 255 SumValue = SumValue + (i - MeanValue) ^ 2 * Hist(i) Next i StdValue = Sqr(SumValue / SourceImHeight / SourceImWidth) StdValue = Format(StdValue, "0.00") ' 保留两位小数 txtNewStd = Str(StdValue) End Sub
Visual Basic 与图像处理 ( 二 ) 3 、灰度直方图 灰度直方图是描述图像中像素灰度分布的一个统计图,简而言之就是描述图像中每个灰度值像素的个数或者概率,横坐标对应就是图像的灰度级别,纵坐标是该灰度级别对应的像素个数(或概率)。要得到图像的灰度直方图,首先要完成各灰度级别对应像素个数的统计,将统计结果存放于 Hist 数组中,然后再根据这个数组进行直方图的绘制。 基于前面的编程基础,相信要完成直方图统计应该都没有问题,这里要简要介绍一下直方图绘制的方法。前文提及过, PictureBox 不仅支持图像的读写,还支持图形的绘制,在这里为简便起见,只用一系列直线进行直方图的绘制, PictureBox 的 Line 方法可用于直线的绘制,其原型如下: object.Line (x1, y1) - (x2, y2), , 这里 (x1,y1) 为直线的起点, (x2,y2) 为直线的终点,如果没有 Step 表示直接从起点画到终点,如果有关键字 Step ,表示分别沿着 x1 , y1 在横向和纵向绘制 x2, y2 的长度, color 用于设置直线的颜色,可用 RGB 函数进行设定。如果使用了 B 选项,则 F 选项规定矩形以矩形边框的颜色填充。不能不用 B 而用 F 。如果不用 F 光用 B ,则矩形用当前的 FillColor 和 FillStyle 填充, FillStyle 的缺省值是 Transparent ,由于本例中只画直线,因此 B 选项和 F 选项都不选用。 在直方图绘制时,首先要确定每个灰度等级对应的线段长度,这里采用常见的一种方法,即首先找出统计概率最高的灰度等级,设定其绘制长度,其余灰度等级绘制的线段长度与该灰度等级成对比,假设概率最高的灰度等级对应的绘制长度为 L ,其他灰度等级的线段绘制长度可按照下面的方式进行计算: L gray = L * Hist / Hist max 首先对程序界面进行设计,本例主要由两个 PictureBox 组成,其中一个 PictureBox 用于存放图像,另一个用于直方图的绘制。用于直方图绘制的 PictureBox 宽度直接设置为 256 个像素,即每个灰度等级绘制的直线占的宽度都是 1 个像素。该程序的软件运行界面如下: 直方图绘制按钮对应的代码如下: Private Sub cmdHist_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Hist(0 To 255) As Long Dim maxHist As Long, L As Integer, L0 As Integer ' 直方图统计 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i ' 直方图绘制 ' 第一步,寻找 Hist 数组中的最大值,即灰度等级统计概率最高者 maxHist = Hist(0) For i = 1 To 255 If maxHist Hist(i) Then maxHist = Hist(i) Next i ' 绘制直方图,其中最高概率的灰度等级绘制长度与 PictureBox 的高度一致 L = PicHist.Height For i = 0 To 255 L0 = L * Hist(i) / maxHist PicHist.Line (i, L - 1)-Step(0, -L0), RGB(0, 0, 255) ' 绘制蓝色线条 Next i End Sub
Visual Basic 与图像处理 ( 二 ) 2 、图像的特征值计算 这里所说图像的特征值是指可以直接从图像中提取出来的特征参数,常用于对图像的整体性评价,如图像的灰度均值可以用于判断图像整体亮度的高低。在图像灰度化的基础上可以很便捷的完成图像特征值的计算,本例中以两个基本的特征参数计算作为示范:均值和标准差。从本质上来说,图像灰度化以后就相当于一个二维矩阵,因此均值的计算只要求得图像中所有像素点的灰度值之和,再除以图像的高度与宽度的乘积即可,图像的标准差计算方法与此类似。以 MeanValue 和 StdValue 分别表示图像的均值和标准差,其计算公式如下: 首先设计程序的软件界面,本例中运行界面如下图: 同样“读入图像”按钮的代码与前文类似,这里给出特征值计算按钮对于的程序代码: Private Sub cmdCalFeature_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim SumValue As Long Dim MeanValue As Single Dim StdValue As Single ' 图像均值计算 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b SumValue = SumValue + GrayValue Next j Next i MeanValue = SumValue / SourceImHeight / SourceImWidth MeanValue = Format(MeanValue, "0.00") ' 保留两位小数 txtMeanValue = Str(MeanValue) ' 图像标准差计算 SumValue = 0 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b SumValue = SumValue + (GrayValue - MeanValue) ^ 2 Next j Next i StdValue = Sqr(SumValue / SourceImHeight / SourceImWidth) StdValue = Format(StdValue, "0.00") ' 保留两位小数 txtStdValue = Str(StdValue) End Sub
Visual Basic 与图像处理 ( 二 ) 有了上面介绍的 Point 和 PSet 方法以后就可以进入真正的图像处理阶段了,与平时学习一样,这里同样从最简单的图像处理技术——点运算开始讲起。点运算简而言之就是对图像进行逐点运算,得到所需要的特征参数或者新的图像。点运算之所以简单是因为点运算每次只需要考虑当前一个像素点的颜色值,当然点运算不可能改变图像内的空间关系。 点运算中最简单是获得图像的特征参数包括均值、方差等,另一种就是按照特定的方式对图像的直方图进行改变,这里的特定方式可以看成是从像素到像素的操作,常见的有对比度增强、对比度拉伸或灰度变换。后面将从图像灰度化、特征参数计算、直方图统计、灰度线性变换、灰度拉伸、直方图均衡化等几种常用的实例进行讲解,同时以 Visual Basic 软件进行算法实现。 1、 图像的灰度化 图像的灰度化是指将原始的彩色图像转换为灰度图像,这也是后续其他点运算操作的先前操作,也就是说点运算是基于灰度图像进行的。彩色图像中 Red 、 Green 、 Blue 三个分量值相等时,呈现出的就是一种灰度化的效果,因此要讲彩色图像转换为灰度图像只要将上述三个分量值设置为同样的值即可。这里需要讨论的只是设置灰度值的方法,有一种最简单的方法是取三个分量中的一个或者是平均值,但在实践中发现这种简单的转换方法与人的视觉习惯不太符合,因此有许多公司在研究这种灰度转换模型,在本节中,我们采用加权平均的方法实现图像的灰度化,方法如下: Gray = 0.3*Red+0.59*Green+0.11*Blue 下面通过一个实例实现彩色图像的灰度化,本例是后续点运算的基础,同样第一次涉及图像处理的完整流程,因此讲述的稍微详细一点。 为了强调原始图像与目标图像的概念,这也是在一般图像处理软件里面都会涉及的,本例中在窗体中放置两个 PictureBox 控件,分别用于存放原始图像与目标图像。 读取图像的方法与前文介绍的一致,即用 LoadPicture 函数进行图像读取,在获得原始图像的高度和宽度以后,按照预定方式进行目标图像的高度和宽度设置,然后利用循环语句遍历原始图像,逐个改变原始图像中每个像素点的值,并将其赋值到目标图像中,就可以完成图像的点运算。这里的循环语句是后面其他图像处理中也经常需要使用的一个标准过程,其基本格式如下 For i = 0 To h - 1 For j = 0 To w - 1 PixelValue = Picture1.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ’ 插入图像处理的过程,对 r, g, b 进行处理 …….………………………………. Picture2.PSet (j, i), RGB(RValue, GValue, BValue) Next j Next i 这里需要注意观察的是 Point 和 PSet 方法中坐标的位置,第一个坐标是横坐标,第二个坐标是纵坐标。 有了这个标准过程就可以理解图像灰度化处理的基本代码了,首先设计该程序的软件界面,效果如下图所示: 这里读入图像按钮的代码与前文类似,这里不在阐述,下面是灰度化按钮对于代码: Private Sub cmdGray_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ' 彩色图像的灰度化处理 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b PicDest.PSet (j, i), RGB(GrayValue, GrayValue, GrayValue) Next j Next i End Sub
Visual Basic 与图像处理(二) 从本节开始,正式开始进入 Visual Basic 图像处理的内容,在正文中会结合一些实例来讲解 Visual Basic 处理图像的方法,当然在初始阶段,一切从简单的开始,在处理图像时也仅用 Point 与 PSet 相结合完成图像的读和写的两个过程。 1. 读入和保存图像 VB 中读入图像可以采用 LoadPicture 函数直接进行,当然也可以采用读取文件的方法直接读取图像数据,然后将图像数据在 PictureBox 中进行绘制。为了便于教学,一般都直接采用 LoadPicture 函数进行图像的读取, LoadPicture 函数的原型如下: LoadPicture ( , , , , ) as TPictureDisp 在我们读入图像时,一般直接使用下面的格式: Picture1.Picture=LoadPicture (FileName) 当 FileName 为空时,清空 PictureBox 中图像。 如果直接使用固定的 FileName 字符常量时,可读入存储器中固定位置的图像,如果希望以对话框的形式进行图像的选择性读取,可以使用 CommonDialog 控件实现。 图像保存对打开类似,可以使用写文件的形式进行图像数据的存储,在 Visual Basic 中提供了配合 PictureBox 控件专门的文件保存函数 SavePicture ,其函数原型如下: SavePicture ( Picture as TPictureDisp, FileName as String) 下面以一个实例示范如何进行图像读取和保存: 窗体中放有 1 个 PictureBox 控件用于显示图像, 2 个 CommandButton 分别用读取和保存图像, 1 个 CommodDialog 控件用于调用对话框。窗体外观如下: 注意设置 PictureBox 控件的相关属性。本例对应的相关代码如下: Option Explicit Private Sub cmdOpenImage_Click() Dim strFileName As String CommonDialog1.Filter = "bmp|*.bmp|jpg|*.jpg|gif|*.gif" ' 文件过滤,可以打开上述三类图像 CommonDialog1.ShowOpen If CommonDialog1.FileName "" Then strFileName = CommonDialog1.FileName PicShowImage.Picture = LoadPicture(strFileName) End If End Sub Private Sub cmdSaveImage_Click() Dim strFileName As String CommonDialog1.Filter = "bmp|*.bmp|jpg|*.jpg|gif|*.gif" ' 文件过滤,可以打开上述三类图像 CommonDialog1.ShowSave If CommonDialog1.FileName "" Then strFileName = CommonDialog1.FileName SavePicture PicShowImage.Picture, strFileName End If End Sub 2 、 PictureBox 控件中像素点颜色值存储格式 在 PictureBox 读入图像以后,像素点以长整型的格式存储在控件之中,利用 Point 方法可以实现像素点颜色值的读取,具体方法如下: Picture1.Point (x, y), 其中 x 为横坐标, y 为纵坐标。 在使用中常采用以下格式得到对应的值: Dim PixelValue as Long PixelValue=Picture1.Point (x, y) 为了便于后续运算,一般要完成颜色数据的分离,即将这个长整型的数转化为对应的 Red 、 Green 、 Blue 三个分量的值。在转化之前,首先看一下颜色值的存储方法,在 Visual Basic 中颜色点以下面的格式进行存储 : 其中第一个字节一般不使用,所以这里只讨论后面三个字节的分离,在数据合成时,上述三个分量分别占 1 个字节,如果将其理解为 256 进制就比如容易理解了,相当于十进制中的个位、十位和百位,只是在显示的时候还是以十进制的形式进行显示而已,如果要分离上述数据就比较简单了,只要将十进制转化为对应的 256 进制就可以了。十进制转化为二进制是除 2 取余法,转化为 256 进制也是采用同样的方法,除 256 取余即可。 下面就是作者在授课是经常采用的一种颜色数据分离方法 Dim r as Integer, g as Integer, b as Integer r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 3 . PictureBox 颜色点的写入 有了 Point 方法可以从 PictureBox 控件中读取颜色点值,对用还需要将某个颜色点值写入到对应的 PixtureBox 控件之中,这里采用与 Point 对用的 PSet 方法, PSet 的使用格式如下: Picture1.PSset (x, y), Color 这里的 Color 同样对应一个长整型的颜色数值,对上述数据分离对应的时,在数据处理时往往知道的是 Red, Green, Blue 三个分量的值,需要将这三个分量进行合成,得到长整型的颜色数值,合成方法与前面讲的非常类似,具体方法如下: PixelValue= r+256*g+256*b 当然在实际使用中还可以直接利用 RGB 函数进行颜色值的合成,使用方法如下: PixelValue=RGB(r, g, b) 下面结合一个实例结束这一部分内容,在完成图像读和写以后,本例中完成图像高度和宽度的自动读取,同时利用 Point 方法读取某个指定位置像素点的值,最后利用 PSet 方法将图像的左上角一块区域设置为红色。本例的运行结果如下: 对应的代码分别如下: Option Explicit Dim ImageHeight As Integer, ImageWidth As Integer Private Sub cmdOpenImage_Click() Dim strFileName As String CommonDialog1.Filter = "bmp|*.bmp|jpg|*.jpg|gif|*.gif" ' 文件过滤,可以打开上述三类图像 CommonDialog1.ShowOpen If CommonDialog1.FileName "" Then strFileName = CommonDialog1.FileName PicShowImage.Picture = LoadPicture(strFileName) End If ImageHeight = PicShowImage.Height ImageWidth = PicShowImage.Width Text1 = Str(ImageHeight) Text2 = Str(ImageWidth) End Sub Private Sub cmdPoint_Click() Dim r As Integer, g As Integer, b As Integer Dim x As Integer, y As Integer Dim pixelvalue As Long x = Val(Text3): y = Val(Text4) pixelvalue = PicShowImage.Point(x, y) r = pixelvalue Mod 256 g = (pixelvalue \ 256) Mod 256 b = pixelvalue \ 65536 Text5 = Str(r) Text6 = Str(g) Text7 = Str(b) End Sub Private Sub cmdPSet_Click() Dim i As Integer, j As Integer For i = 0 To 20 For j = 0 To 20 PicShowImage.PSet (i, j), RGB(255, 0, 0) Next j Next i End Sub
先介绍下我的机器软件配置, WIN7 64bit, Matlab R2011b 64bit, VS2010. 在论坛上找了很久,看了N多帖子. 都无法让机器上VS2010调用R2011b的函数和引擎,总是出现错误信息: Link error: can't open "libmx.lib libmat.lib libeng.lib". 结果在Mathworks 的网页上发现了如下帖子,总算成功编译通过了. http://www.mathworks.com/support/solutions/en/data/1-FWTSV5/index.html?product=MLsolution=1-FWTSV5 文章的标题是: How do I setup a Visual Studio 2010 Express Project in order to run the engdemo.cpp example in MATLAB 7.13 (R2011b) on my 64bit machine? 后来发现,需要特别注意的是这里: “Configuration Properties” - “Linker” - “Input” and add libmx.lib, libmat.lib and libeng.lib as additional dependencies. 在输入libmx.lib, libmat.lib, libeng.lib 到 Additional Dependencies 框中时候, 必须用分号(;)分隔, 就是这样: libmx.lib; libmat.lib;libeng.lib; 否则就会出现can't open "libmx.lib libmat.lib libeng.lib".的错误信息. BTW,我的VS2010 是home premieum版, MATLAB 2011b
什么是神经美学? What is neuroaesthetics? Apparently it is an emerging interdisciplinary field between neuroscience and aesthetics. Although I heard the term long before, I essentially know nothing of it. This weekend there will be a conference on neuroaesthetics at UC Berkeley ( http://www.minervaberkeley.org/conferences/importance-of-being-playful ). As I am trying to determine whether or not to attend the conference, I searched the Internet to try and learn a bit more about this so-called neuroaesthetics discipline. I found that the wiki page on neuroaesthetics is a good introduction but is in English only ( http://en.wikipedia.org/wiki/Neuroesthetics ). I also found an introduction paper in Chinese, which is available as a PDF file for downloading at: http://journal.psych.ac.cn/jinzhan/qikan/manage/wenzhang/120505.pdf . If anyone interested in learning a bit more about neuroaesthetics, download it! Mona Lisa by Leonardo da Vinci: What are your brain activities when you see a painting like this?