Infogosoft / jsdicom

dicom library and viewer in javascript
95 stars 38 forks source link

adapting shaders in order to implement convolution 3x3 kernel #19

Closed q4z1 closed 8 years ago

q4z1 commented 10 years ago

Hi there,

i am extending your great viewer in order to do some filtering (blur, smooth for example) using framebuffers. I already figured out, how to do it with normal images, but i get stucked with the different fragment_shaders you use. Do you know, how to integrate a 3x3 kernel into the existing shaders - just like the way it works here with normal pictures:

var vertex_shader_kernel = "\ attribute vec2 a_position;\ attribute vec2 a_texCoord;\ uniform vec2 u_resolution;\ uniform float u_flipY;\ varying vec2 v_texCoord;\ void main() {\ vec2 zeroToOne = a_position / u_resolution;\ vec2 zeroToTwo = zeroToOne * 2.0;\ vec2 clipSpace = zeroToTwo - 1.0;\ gl_Position = vec4(clipSpace * vec2(1, u_flipY), 0, 1);\ v_texCoord = a_texCoord;\ }";

var fragment_shader_kernel = "\ precision mediump float;\ uniform sampler2D u_image;\ uniform vec2 u_textureSize;\ uniform float u_kernel[9];\ varying vec2 v_texCoord;\ void main() {\ vec2 onePixel = vec2(1.0, 1.0) / u_textureSize;\ vec4 colorSum =\ texture2D(u_image, v_texCoord + onePixel * vec2(-1, -1)) * u_kernel[0] +\ texture2D(u_image, v_texCoord + onePixel * vec2( 0, -1)) * u_kernel[1] +\ texture2D(u_image, v_texCoord + onePixel * vec2( 1, -1)) * u_kernel[2] +\ texture2D(u_image, v_texCoord + onePixel * vec2(-1, 0)) * u_kernel[3] +\ texture2D(u_image, v_texCoord + onePixel * vec2( 0, 0)) * u_kernel[4] +\ texture2D(u_image, v_texCoord + onePixel * vec2( 1, 0)) * u_kernel[5] +\ texture2D(u_image, v_texCoord + onePixel * vec2(-1, 1)) * u_kernel[6] +\ texture2D(u_image, v_texCoord + onePixel * vec2( 0, 1)) * u_kernel[7] +\ texture2D(u_image, v_texCoord + onePixel * vec2( 1, 1)) * u_kernel[8] ;\ float kernelWeight =\ u_kernel[0] +\ u_kernel[1] +\ u_kernel[2] +\ u_kernel[3] +\ u_kernel[4] +\ u_kernel[5] +\ u_kernel[6] +\ u_kernel[7] +\ u_kernel[8] ;\ if (kernelWeight <= 0.0) {\ kernelWeight = 1.0;\ }\ gl_FragColor = vec4((colorSum / kernelWeight).rgb, 1);\

}

I'd also like to contribute my results when I am done, because you did a great Job so far!

Regards,

q4z1

daniel-lundin commented 10 years ago

Hi,

It would be really cool to add convolution indeed! I think you need to calculate the intensity(windowing) of the neighbouring pixels first and then perform the convolution in the fragment shader. I don't think any changes to the vertex shader should be needed? I have to play with a bit myself before I can help you further.

Thanks for your effort so far!

q4z1 commented 10 years ago

Hello diggidanne,

thx so far. I agree, the vertex shader does not need to be changed. It would be great if you figure out a solution.

I will then first continue on the measuring and angle calculation tool. I hope it is ok, using a transparent second 2d-canvas above the webgl canvas in order to draw the measurement and angle calculation lines? I changed all the event listeners - and all tools are still functioning normal. I must admit, it's much easier to draw in 2D for me, because I am absolutely new to webgl.

See you then.

q4z1

daniel-lundin commented 10 years ago

Hello,

I made a quick sketch on how it may work: https://gist.github.com/diggidanne/7986605 Check out the frament_shader_16. It's a hard coded edge-finding kernel for now, it should probably be sent as a uniform from glpainter.js. I think it may be enough to get you started. Let me know if you have any questions.

2d canvas overlay is probably ok if you can get them synchronized w.r.t to zooming/paning.

Appreciate your efforts!

q4z1 commented 10 years ago

Hello,

thanks for the code - I will try it out immedeately tomorrow morning (CET)!

I finished the angle-tool - working fine. And so far the measuring tool is finished, too. I will have to adapt the zoom synch though.

Were can I put my code to contribute? I'd do it next weekend then.

daniel-lundin commented 10 years ago

To contribute, you should fork the project, make your changes there(to your own fork), then submit a pull request to this project. Github has a lot of good guides on this subject: https://help.github.com/

q4z1 commented 10 years ago

Ok. Was my first idea to fork the project. I will do so. Standby pls till next monday. (I also added some sliders for zooming and window/level - maybe we can discuss how to easily find out the min and the max w/l values - i just took some fixed ranges by now - but a histogram seems to be best choice?)

q4z1 commented 10 years ago

Worked like charm! I dit not even had to use frame_buffers. I just adapted the shader, and also included brightnes and contrast uniforms & calculations ;-) With the rest, I kept on your app/tool/painter structure. You can see the result on the site, I sent you via email. To enable the blur, click on the picture, after enabling the tool.

Thank you very much!

As promised, I'll publish my results next weekend,