HTML 5灰度图像处理练习1:直方图和灰度反转

大多数医学图像都是灰度图像,这个练习也是顺便考察一下HMTL5 Canvas API在医学图像处理方面的潜力。
下面是一个简单 的直方图和灰度反转案例。原理是在Canvas中打开一幅gif或jpg的256级灰度图像,通过context.getImageData()获得象素 矩阵。然后,对这个象素矩阵进行统计,可以生成直方图。或者,对这个矩阵进行灰度反转之后,用context.putImageData()重新显示出 来。顺带提一下,画直方图的时候,我是直接在imagedata的象素矩阵上画线的,而没有用lineTo之类的API,因为我发现后者画出来的线的边缘 都做了模糊化处理,只为了让人眼看起来比较舒服,但在科学或医学领域应该不能允许多余的像素。
下面的代码可以直接复制到本地一个html文件中,然后用IE9/Opera10/etc.打开。至于其中用到的512*512尺寸的CT、SMPTE和戴帽子女孩的图片,读者可以在网上自行下载。其中那个著名的戴帽子女孩,用“灰度图象”作为关键字就能找到。

双击代码全选

1

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

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

<!DOCTYPE html>  

<html>  

    <head>  

        <meta charset="utf-8"/>  

        <title>Grayscale Image Test</title>  

        <style type="text/css">  

        table {margin:auto;}  

        </style>  

    </head>  

    <body style="background-color: #eeeeee;" mce_style="background-color: #eeeeee;">  

        <table>  

            <tr align="center"><td colspan="2"><h3>Grayscale Image Test</h3><hr height="1px"/></td>  

          </tr>  

            <tr>  

                <td align="right">  

                    <button id="invertImage" onclick="invertImage();return true;">Invert</button>  

                    <button id="invertImage" onclick="loadImage(girlUri);return true;">Reset</button>  

                    <button id="smpteImage" onclick="loadImage(smpteUri);return true;">SMPTE</button>  

                    <button id="ctImage" onclick="loadImage(ctUri);return true;">CT</button>  

                </td>  

                <td>  

                </td>  

            </tr>  

            <tr align="center">  

                <td><canvas id="imageviewer" width="512px" height="512px" style="border: 1px solid;" mce_style="border: 1px solid;" /></td>  

              <td><canvas id="statistic" width="256" height="512px" style="border: 1px solid;" mce_style="border: 1px solid;" /></td>  

            </tr>  

            <tr align="center"><td colspan="2">© May, 2011, lifegame@263.net</td>  

            </tr>  

        </table>  

    </body>  

    <script>  

        var ctUri = 'ct.jpg';  

        var smpteUri = 'smpte.gif';  

        var girlUri = 'dmtjc5016.gif';  

        var icanvas = document.getElementById('imageviewer');  

        var icanvasWidth = parseInt(icanvas.getAttribute("width"));   

        var icanvasHeight = parseInt(icanvas.getAttribute("height"));   

        var icontext = icanvas.getContext('2d');  

        var scanvas = document.getElementById('statistic');  

        var scanvasWidth = parseInt(scanvas.getAttribute("width"));   

        var scanvasHeight = parseInt(scanvas.getAttribute("height"));   

        var scontext = scanvas.getContext('2d');  

                

        function loadImage(uri){  

            var img = new Image();  

            img.src = uri;  

            img.onload = function(){  

                icontext.drawImage(img,0,0);  

                loadStatistic();  

            };  

        }  

                

        function loadStatistic(){  

            var imgData = icontext.getImageData(0,0,icanvasWidth,icanvasHeight);  

            var pixTotal = imgData.height*imgData.width;  

            var pixCount = [];  

            for(i=0;i<256;i++) pixCount[i]=0;  

            for(y=0;y<imgData.height;y++){  

                    for(x=0;x<imgData.width;x++){  

                        var pv = Math.min(255,imgData.data[(y*imgData.width+x)*4]);  

                        pixCount[pv]++;  

                        }  

                    }  

            scontext.clearRect(0,0,scanvasWidth,scanvasHeight);  

            var stImg = scontext.getImageData(0,0,scanvasWidth,scanvasHeight);  

            for(x=0;x<256;x++){  

                var c = pixCount[x];  

                var h = stImg.height - Math.round(stImg.height*c/pixTotal);  

                for(y=h;y<stImg.height;y++){  

                    var i = (y*stImg.width+x)*4;  

                  stImg.data[i]=stImg.data[i+1]=stImg.data[i+2]=0;  

                  stImg.data[i+3]=255;  

                }  

            }  

            scontext.putImageData(stImg,0,0);  

        }  

                

        function invertImage(){  

            var imgData = icontext.getImageData(0,0,icanvasWidth,icanvasHeight);  

            for(y=0;y<imgData.height;y++){  

                    for(x=0;x<imgData.width;x++){  

                        var i = (y*imgData.width+x)*4;  

                        var pv = Math.abs(255-imgData.data[i]);  

                        imgData.data[i]=imgData.data[i+1]=imgData.data[i+2]=pv;  

                    }  

                }  

            icontext.putImageData(imgData,0,0);  

            loadStatistic();  

        }  

                    

        window.addEventListener("load", loadImage(girlUri), true);  

    </script>  

<html>