HTML5 grayscale image processing exercise 2: window width and window adjustment

Source: Internet
Author: User
Tags scale image

The gray level of most medical images is much higher than 256, but the general computer screen only supports 256 levels, coupled with the natural sensitivity of human eyes (mostly only up to 16 levels ), as a result, humans can only observe the vast gray world through a small window. Therefore, just as astronomy cannot do without telescopes, modern radiologists cannot do without wide window spaces.

Some imaginative readers will ask, can we use HTML5 for PACs image workstations in the future? So far, no one has been able to answer the question. In the true sense, PACs image workstations also have many complex mechanisms, such as large-scale image loading, personalized layout, convenient browsing and navigation tools, allows users to quickly locate the desired image in a large sequence, or find the area to be carefully studied in a large image, as well as the complex memory management and network communication behind all of this. Although HTML5 can be used to handle the wide window space within 200 lines of code, it is also the most common function on most workstations, however, this is only a tiny step towards a pure web platform workstation without plug-ins, concerning the security of canvas cross-origin image access, HTML5 file API, websocket API, the future development of webstorage APIs requires further attention. Of course, another option is to place all of these simple spatial and gray-scale transformation logic on the server side.

At least a few years ago, it was hard to imagine using JavaScript to adjust the window width. First, you cannot find the pixel processing API that javascript can call. Second, Javascript Engines in most browsers are slow. The emergence of HTML5 may provide some possibility. But I am also a little worried. Does HTML5 API really need to replace all desktop applications? If so, will HTML5 become too complicated? Is there a suitable technical architecture and workflow to control this complexity? In this avid age, HTML5 technical decision makers should seriously consider what to do and what not to do, because in the IT field, there is a tiny difference in functionality everywhere, cases with different results.

The following is a simple case of window width and bit adjustment. You can copy it to a local HTML file and open it with ie9/opera10/etc. The principle is to first initialize a 512*512 size matrix, which is filled with 12 gray values (from 0 to 4096 ). To facilitate the Observation of the Effect of window width and bit adjustment, the gray-scale distribution in this matrix is designed in a manner similar to SMPTE. Then, adjust the window width and bit through the input control (that is, drag a bar) with the type of range in HTML. Unfortunately, ie9 does not support this control, therefore, simply drag the mouse to add: horizontal drag to change the window width, vertical drag to change the window position. During step-by-step programming, to roughly verify the correctness of each step, I also added a canvas dedicated to displaying the original data and PV (presentation value) histograms on the page, however, I removed the code from the last release. for Readers interested in generating histograms, refer to the previous blog.

After completing the work, we found that there is still a small gap between ie9 and opera10. In addition to the support for the range-type input control and the performance of the Javascript script engine, I also noticed a more terrible flaw. I don't remember what to say in terms of computer graphics. If radiology is used, this quality indicator may be measured by line. When I add black and white lines separated by one pixel to my test pattern, I use the same monitor, it is found that the line area displayed by ie9 is very distorted (there is a significant difference in density observed by the human eye), but the opera10 display is basically not distorted (and it is strange that after being uploaded to csdn, the image is automatically converted to gif. It is normal to observe the image on opera10, and the image is distorted on ie9 ). I hope someone will tell me how opera10.

I tried to run opera10 on Intel I3 m350 with a mouse to adjust the window width. The speed was barely acceptable (compared with the workstation of the desktop version ), however, the algorithms I use are not optimized. Interested readers can make some improvements based on the paper "DICOM medical image window transformation acceleration algorithm". I believe that after the improvement, the performance of mouse drag adjustment should not be much different from that of the desktop workstation. Of course, we still need to perform further experiments on larger General images (although some people insist that the general image adjustment window may be of little significance, or want to adjust it with some curves ).

Finally, I hope that IE will make faster progress in HTML5 support. After all, the Internet Explorer penetration rate on the Microsoft platform is still very high. Ie10 has proposed the HTML5 localization concept to see to what extent they can finally implement it. Although Microsoft is very large, most of them are still very flexible. Not only does it not miss the opportunity as Kodak did before, but sometimes it will slaughter technologies that have been around for many years, for example, VB/COM in 1990s and winform in the year 00 s, even though they were excellent. I don't know if sliverlight will be slaughtered after Microsoft embraces HTML5.

 

 

<! Doctype HTML> <br/> <pead> <br/> <meta charset = "UTF-8"/> <br/> <title> grayscale indexing wing Test </title> <br/> <style type = "text/CSS"> <br/> table {margin: auto ;} <br/> </style> <br/> </pead> <br/> <body> <br/> <Table> <br/> <tr align = "Center "> <TD> <p> grayscale image test </p> <HR Height =" 1px "/> </TD> <br/> </tr> <br/> <tr> <br/> <TD align = "right"> <br/> ww (<span id = "spanww"> </span>): <input id = "rangew W "type =" range "min =" 0 "max =" 4096 "onchange =" setwindow (); "/> <br/> WC (<span id =" spanwc "> </span> ): <input id = "rangewc" type = "range" min = "0" max = "4096" onchange = "setwindow (); "/> <br/> <button id =" resetimage "onclick =" LoadImage (); Return true; "> Reset </button> <br/> </TD> <br/> </tr> <br/> <tr align =" center "> <br/> <TD> <canvas id = "imageviewer" width = "512px" Height = "512px" style = "border: 1px solid; "mce_style = "Border: 1px solid;"/> </TD> <br/> </tr> <br/> <tr align = "center"> <TD> May, 2011, lifegame@263.net </TD> <br/> </tr> <br/> </table> <br/> </body> <br/> <SCRIPT> <br/> vaR patterndata = []; <br/> var patternwidth = 512; <br/> var patternheight = 512; <br/> var patternmaxgray = 0x0fff; </P> <p> function getpatterndata (X, y) {<br/> return patterndata [y * patternwidth + X]; <br/>}</P> <p> function setpatterndata (X, Y, V) {<B R/> patterndata [y * patternwidth + x] = V; <br/>}</P> <p> function initpatterndata () {<br/> function fillrect (X, y, W, H, v) {<br/> var Maxx = x + W; <br/> var Maxy = Y + h; <br/> for (I = x; I <Maxx; I ++) {<br/> for (j = y; j <Maxy; j ++) {<br/> setpatterndata (I, j, V); <br/>}< br/> function fillgradientrect (x, y, w, H, F, T) {<br/> var Maxx = x + W; <br/> var Maxy = Y + h; <br/> for (I = x; I <Maxx; I ++) {<br/> var v = F + math. round (t-f) * (I-x)/W); <br/> for (j = y; j <Maxy; j ++) {<br/> setpatterndata (I, j, v); <br/>}< br/> function fillgrid (C, R, V) {<br/> var x = C * 128; <br/> var y = r * 128; <br/> fillrect (X, Y, 128,128, V ); <br/>}< br/> function fillgradientgrid (C, r, f, T) {<br/> var x = C * 128; <br/> var y = r * 128; <br/> fillgradientrect (X, Y, 128,128, F, t ); <br/>}< br/> function drawlines (X, Y, W, H, d) {<br/> var V; <br/> var Maxx = x + W; <br/> VaR Maxy = Y + H; <br/> If (D = 1) {<br/> for (I = x; I <Maxx; I ++) {<br/> V = (I % 2) = 0 )? 0: patternmaxgray; <br/> for (j = y; j <Maxy; j ++) {<br/> setpatterndata (I, j, V ); <br/>}< br/> else {<br/> for (I = y; I <Maxy; I ++) {<br/> V = (I % 2) = 0 )? 0: patternmaxgray; <br/> for (j = x; j <Maxx; j ++) {<br/> setpatterndata (J, I, V ); <br/>}< br/> function filllinegrid (C, R) {<br/> var x = C * 128; <br/> var y = r * 128; <br/> drawlines (X, Y, 64,128, 1 ); <br/> drawlines (x + 64, Y, 64,128, 0); <br/>}< br/> fillgrid (, 0 ); <br/> fillrect (32, 32, 64, 64, patternmaxgray * 0.05); <br/> fillgrid (0.1, patternmaxgray *); <br/> fillgrid, patternmaxgray * 0.2); <br/> fillgrid (0.3, patternmaxgray * 0.4); <br/> fillgrid (, patternmaxgray *); <br/> fillgrid, patternmaxgray * 0.5); <br/> fillgrid (0.6, patternmaxgray * 0.7); <br/> fillgrid (, patternmaxgray *); <br/> fillgrid, patternmaxgray * 0.8); <br/> fillgrid (0.9, patternmaxgray *); <br/> fillgrid (, patternmaxgray ); <br/> fillrect (256 + 32,256 + 32, 64, 64, patternmaxgray * 0.95); <br/> filllinegrid (); <br/> fillgradientgrid (, 0, patternmaxgray/4); <br/> fillgradientgrid (2/4, patternmaxgray/4, patternmaxgray * 2/4); <br/> fillgradientgrid (3/4, patternmaxgray *, patternmaxgray ); <br/> fillgradientgrid (3, 3, patternmaxgray * 3/4, patternmaxgray ); <br/>}< br/> </SCRIPT> <br/> <SCRIPT> <br/> var icanvas = document. getelementbyid ('imageviewer '); <br/> var icanvaswidth = parseint (icanvas. getattribute ("width"); <br/> var icanvasheight = parseint (icanvas. getattribute ("height"); <br/> var icontext = icanvas. getcontext ('2d '); <br/> var iswindowing = 0; <br/> var beginpointx = 0; <br/> var beginpointy = 0; <br/> var wwstep = 5; <br/> var wcstep = 5; </P> <p> function LoadImage () {<br/> icanvas. onmousedown = function (e) {<br/> iswindowing = 1; <br/> If (E. offsetx) {<br/> beginpointx = E. offsetx; <br/> beginpointy = E. offsety; <br/>}< br/> else if (E. layerx) {<br/> beginpointx = E. layerx; <br/> beginpointy = E. layery; <br/>}< br/> icanvas. onmouseup = function (e) {<br/> iswindowing = 0; <br/> If (E. offsetx) {<br/> X = E. offsetx; <br/> Y = E. offsety; <br/>}< br/> else if (E. layerx) {<br/> X = E. layerx; <br/> Y = E. layery; <br/>}< br/> var WW = parseint (rangeww. value); <br/> var WC = parseint (rangewc. value); <br/> WW = WW + (X-beginpointx) * wwstep; <br/> WC = WC + (Y-beginpointy) * wcstep; <br/> updatewindow (WW, WC); <br/>}< br/> function updatewindow (WW, WC) {<br/> loadpattern (WW, WC ); <br/> rangeww. value = WW; <br/> rangewc. value = WC; <br/> spanww. innerhtml = WW; <br/> spanwc. innerhtml = WC; <br/>}< br/> initpatterndata (); <br/> updatewindow (4096,2048 ); <br/>}</P> <p> function loadpattern (WW, WC) {<br/> function setpoint (IMG, X, Y, PV) {<br/> var I = (y * IMG. width + x) * 4; <br/> IMG. data [I] = IMG. data [I + 1] = IMG. data [I + 2] = PV; <br/> IMG. data [I + 3] = 255; <br/>}< br/> function getpresentationvalue (V, W, c) {<br/> var MINV = c-Math.round (W/2); <br/> If (v <MINV) return 0; <br/> var maxv = C + math. round (W/2); <br/> If (V> maxv) return 255; <br/> var Pv = math. round (255 * (V-MINV)/W); <br/> If (Pv <0) return 0; <br/> If (Pv> 255) return 255; <br/> return PV; <br/>}< br/> var imgdata = icontext. getimagedata (0, 0, icanvaswidth, icanvasheight); <br/> for (y = 0; y <patternheight; y ++) {<br/> If (Y> = imgdata. height) break; <br/> for (x = 0; x <patternwidth; X ++) {<br/> If (x> = imgdata. width) break; <br/> var v = getpatterndata (x, y); <br/> var Pv = getpresentationvalue (v, WW, WC ); <br/> setpoint (imgdata, X, Y, PV); <br/>}< br/> icontext. putimagedata (imgdata, 0, 0); <br/>}</P> <p> function setwindow () {<br/> var WW = parseint (rangeww. value); <br/> var WC = parseint (rangewc. value); <br/> loadpattern (WW, WC); <br/> spanww. innerhtml = WW; <br/> spanwc. innerhtml = WC; <br/>}</P> <p> window. addeventlistener ("LOAD", LoadImage (), true); <br/> </SCRIPT> <br/> <HTML>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.