Author Topic: Cosine Transform  (Read 7137 times)

0 Members and 1 Guest are viewing this topic.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Cosine Transform
« on: June 27, 2018, 07:03:36 pm »
Neat program I found:

Code: QB64: [Select]
  1. defint a-z
  2.  
  3. dim shared mx,my,mbl,mbr,mw
  4. pi = 3.141593
  5.  
  6. sw = 800
  7. sh = 600
  8.  
  9. dim xx(sw - 1), x(sw - 1)
  10.  
  11. screen _newimage(sw,sh,32)
  12.  
  13.         getmouse
  14.  
  15.         line(0, 0)-(sw, sh), _rgb(0,0,0), bf
  16.  
  17.         line(sw/2, 0)-(sw/2, sh), _rgb(255,0,0)
  18.         line(0, sh/4)-(sw, sh/4), _rgb(255,0,0)
  19.         line(0, 3*sh/4)-(sw, 3*sh/4), _rgb(255,0,0)
  20.  
  21.         ox = 0
  22.         oy = 3*sh/4 - x(0)
  23.         for i = 0 to ubound(xx)
  24.                 if xx(i) <> 0 then line(i, sh/4)-step(0,-xx(i))
  25.  
  26.                 line(ox, oy)-(i, 3*sh/4 - x(i))
  27.                 ox = i
  28.                 oy = 3*sh/4 - x(i)
  29.         next
  30.  
  31.         'if m = 0 then
  32.                 line(mx, sh/4)-(mx, my)
  33.         'end if
  34.  
  35.         if mbl then
  36.                 do
  37.                         getmouse
  38.                 loop until mbl = 0
  39.  
  40.                 xx(mx) =  sh/4 - my
  41.  
  42.                 for i = 0 to ubound(x)
  43.                         x(i) = x(i) + xx(mx) * cos(2*pi*i*(mx - sw/2)*(sw))
  44.                 next
  45.         end if
  46.  
  47.         _display
  48.  
  49.  
  50. sub getmouse ()
  51.         do
  52.                 mx = _mousex
  53.                 my = _mousey
  54.                 mbl = _mousebutton(1)
  55.                 mbr = _mousebutton(2)
  56.                 mw = mw + _mousewheel
  57.         loop while _mouseinput
  58.  
  59.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Cosine Transform
« Reply #1 on: June 28, 2018, 10:42:23 am »
Hi v,

This reminds me of Fourier, something about being able to create a wave formula for any finite set of data ie a curve that will fit any graphed set of data points (as long as there is always one and only one y value for any x value AKA a continuous function), something like that..

The only use for it I've witnessed so far was to create a cartoon alien planet surface for lander practice in Just Basic Lander.bas code.

Has anyone another application idea?
« Last Edit: June 28, 2018, 10:43:30 am by bplus »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Cosine Transform
« Reply #2 on: June 28, 2018, 03:55:53 pm »
I think, that this transformation is the basis for JPG and MP3. But as it work, I really do not know. But I have written a head for MP3 if someone wanted to try to disassemble the MP3 samples and then use them in _SNDRAW.

Offline codeguy

  • Forum Regular
  • Posts: 174
    • View Profile
Re: Cosine Transform
« Reply #3 on: June 28, 2018, 07:12:23 pm »
Discrete Cosine Transform is a basis for JPEG compression. I will check this demo out later. I'm sure it will be good.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Cosine Transform
« Reply #4 on: June 29, 2018, 10:24:16 am »
Hi codeguy, one JPG - create / save program is in installation QB64 in programs/samples/n54/big/jpegmake.bas   

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Cosine Transform
« Reply #5 on: July 01, 2018, 10:19:25 am »
Here's a demonstration of how the DCT can be used in image compression.  The second image is about 15% the size of the first since it is created by only using 9 out of 64 DCT coefficients quantized to 256 bits in the inverse computation yet is still quite legible.  It's several steps short of the full JPEG algorithm but demonstrates the same idea.

Code: QB64: [Select]
  1. deflng a-z
  2.  
  3. const n = 8
  4.  
  5. type dct_type
  6.         r as double
  7.         g as double
  8.         b as double
  9.  
  10. type q_type
  11.         r as _unsigned _byte
  12.         g as _unsigned _byte
  13.         b as _unsigned _byte
  14.  
  15. pi = _pi
  16.  
  17. img1 = _loadimage("img/greenland1.png", 32)
  18.  
  19. w = _width(img1)
  20. h = _height(img1)
  21.  
  22. ww = (w\n+1)*n
  23. hh = (h\n+1)*n
  24.  
  25.  
  26. dim dct(ww, hh) as dct_type
  27. dim q(ww, hh) as q_type
  28.  
  29.  
  30. img2 = _newimage(w, h, 32)
  31.  
  32. screen _newimage(w, 2*h, 32)
  33. _putimage (0,0),img1
  34.  
  35. _source img1
  36. _dest img2
  37.  
  38. 'forward DCT
  39. for y=0 to hh-1 step n
  40. for x=0 to ww-1 step n
  41.         for yy=0 to n-1
  42.         for xx=0 to n-1
  43.                 sr = 0
  44.                 sg = 0
  45.                 sb = 0
  46.  
  47.                 for y3=0 to n-1
  48.                 for x3=0 to n-1
  49.                         if (x + x3 > w - 1) then px = x + x3 - n else px = x + x3
  50.                         if (y + y3 > h - 1) then py = y + x3 - n else py = y + y3
  51.  
  52.                         z = point(px, py)
  53.                         r = _red(z)
  54.                         g = _green(z)
  55.                         b = _blue(z)
  56.  
  57.                         c = cos((2*x3 + 1)*xx*pi/(2*n))*cos((2*y3 + 1)*yy*pi/(2*n))
  58.  
  59.                         sr = sr + r*c
  60.                         sg = sg + g*c
  61.                         sb = sb + b*c
  62.                 next
  63.                 next
  64.  
  65.                 if xx = 0 then cu = 1/sqr(2) else cu = 1
  66.                 if yy = 0 then cv = 1/sqr(2) else cv = 1
  67.  
  68.                 dct(x + xx, y + yy).r = sr*cu*cv/(0.5*n)
  69.                 dct(x + xx, y + yy).g = sg*cu*cv/(0.5*n)
  70.                 dct(x + xx, y + yy).b = sb*cu*cv/(0.5*n)
  71.         next
  72.         next
  73.  
  74. 'quantization
  75. dim minr as double, ming as double, minb as double
  76. dim maxr as double, maxg as double, maxb as double
  77.  
  78. minr = 1000000
  79. ming = 1000000
  80. minb = 1000000
  81.  
  82. maxr = -1000000
  83. maxg = -1000000
  84. maxb = -1000000
  85.  
  86. for y=0 to hh
  87. for x=0 to ww
  88.         if dct(x, y).r < minr then minr = dct(x, y).r
  89.         if dct(x, y).g < ming then ming = dct(x, y).g
  90.         if dct(x, y).b < minb then minb = dct(x, y).b
  91.  
  92.         if dct(x, y).r > maxr then maxr = dct(x, y).r
  93.         if dct(x, y).g > maxg then maxg = dct(x, y).g
  94.         if dct(x, y).b > maxb then maxb = dct(x, y).b
  95.  
  96. for y=0 to hh
  97. for x=0 to ww
  98.         q(x, y).r = 255*(dct(x,y).r - minr)/(maxr - minr)
  99.         q(x, y).g = 255*(dct(x,y).g - ming)/(maxg - ming)
  100.         q(x, y).b = 255*(dct(x,y).b - minb)/(maxb - minb)
  101.  
  102. 'inverse DCT
  103. for y=0 to hh-1 step n
  104. for x=0 to ww-1 step n
  105.         for yy=0 to n-1
  106.         for xx=0 to n-1
  107.                 sr = 0
  108.                 sg = 0
  109.                 sb = 0
  110.  
  111.                 for y3=0 to 2 'n-1
  112.                 for x3=0 to 2 'n-1
  113.                         c = cos((2*xx + 1)*x3*pi/(2*n))*cos((2*yy + 1)*y3*pi/(2*n))
  114.  
  115.                         if x3 = 0 then cu = 1/sqr(2) else cu = 1
  116.                         if y3 = 0 then cv = 1/sqr(2) else cv = 1
  117.  
  118.                         'sr = sr + dct(x + x3, y + y3).r*c*cu*cv
  119.                         'sg = sg + dct(x + x3, y + y3).g*c*cu*cv
  120.                         'sb = sb + dct(x + x3, y + y3).b*c*cu*cv
  121.  
  122.                         r = q(x + x3, y + y3).r
  123.                         g =     q(x + x3, y + y3).g
  124.                         b = q(x + x3, y + y3).b
  125.  
  126.                         sr = sr + c*cu*cv*((r/255)*(maxr - minr) + minr)
  127.                         sg = sg + c*cu*cv*((g/255)*(maxg - ming) + ming)
  128.                         sb = sb + c*cu*cv*((b/255)*(maxb - minb) + minb)
  129.                 next
  130.                 next
  131.  
  132.                 sr = sr/(0.5*n)
  133.                 sg = sg/(0.5*n)
  134.                 sb = sb/(0.5*n)
  135.  
  136.                 if (x + xx < w) and (y + yy < h) then pset (x + xx, y + yy), _rgb(sr, sg, sb)
  137.         next
  138.         next
  139.  
  140. _putimage (0,h), img2
  141.  
  142.  
dctc.png
* dctc.png (Filesize: 751.55 KB, Dimensions: 640x852, Views: 501)

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Cosine Transform
« Reply #6 on: July 01, 2018, 01:15:25 pm »
I say straight away that I will need some time to study and understand the function of your program and to study more details of this compression. I appreciate for your demos.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Cosine Transform
« Reply #7 on: July 01, 2018, 11:14:21 pm »
Hi Petr,

I thought I should explain the program. In this particular case I used N=16 for better clarity.  You take the NxN 2-dimensional DCT of each NxN square in the image shown in the first pair of images.  The NxN DCT produces NxN coefficients from NxN pixels.  You notice that most of the 'information' about each square is contained in the top-left corner corresponding to low frequencies.  I guess the property of photographs is that most of their frequency content is focused in the low frequency region.  High frequencies correspond to minute details that might be important in line art but less so in natural photographs and appear mostly gray in the attached image.

Taking the inverse DCT on the NxN DCT coefficients will produce the original images (minus some quantization error if applicable).  We can do a sort of low pass filtering by removing the high frequencies and then reconstructing the image, for example taking the inverse DCT on only (N/2)x(N/2) of the coefficients.  The reconstructed image remains quite legible but takes up only 25% of storage space.  The JPEG algorithm does something similar, but rather than removing high frequencies altogether, it preforms entropy encoding (i.e. Huffman coding) on them which assigns less bits to the less relevant frequencies.

The DCT has several other applications in image processing other than just compression.  Taking the DCT of an entire image and zeroing out frequency components can be done to filter out undesired parts of the image.  For example, if you take a photograph behind a chain-link fence, its repetitive pattern corresponds to particular frequencies in the DCT domain.  Zeroing them out and reconstructing the image might remove the chain-link fence in the new image.  If there's interest, I can make more DCT image processing demos.


Source for attached image:
Code: QB64: [Select]
  1. deflng a-z
  2.  
  3. const n = 16
  4.  
  5. type dct_type
  6.         r as double
  7.         g as double
  8.         b as double
  9.  
  10. type q_type
  11.         r as _unsigned _byte
  12.         g as _unsigned _byte
  13.         b as _unsigned _byte
  14.  
  15. pi = _pi
  16.  
  17. img1 = _loadimage("img/greenland1.png", 32)
  18.  
  19. w = _width(img1)
  20. h = _height(img1)
  21.  
  22. ww = (w\n+1)*n
  23. hh = (h\n+1)*n
  24.  
  25. dim dct(ww, hh) as dct_type
  26. dim q(ww, hh) as q_type
  27.  
  28.  
  29. img2 = _newimage(w, h, 32)
  30. img3 = _newimage(w, h, 32)
  31.  
  32. img1_dct = _newimage(w, h, 32)
  33. img2_dct = _newimage(w, h, 32)
  34. img3_dct = _newimage(w, h, 32)
  35.  
  36. screen _newimage(3*w, 2*h, 32)
  37. _putimage (0,0),img1
  38.  
  39. _source img1
  40.  
  41. 'forward DCT
  42. for y0=0 to hh-1 step n
  43. for x0=0 to ww-1 step n
  44.         for y=0 to n-1
  45.         for x=0 to n-1
  46.                 sr = 0
  47.                 sg = 0
  48.                 sb = 0
  49.  
  50.                 for v=0 to n-1
  51.                 for u=0 to n-1
  52.                         if (x0 + u > w - 1) then px = x0 + u - n else px = x0 + u
  53.                         if (y0 + v > h - 1) then py = y0 + v - n else py = y0 + v
  54.  
  55.                         z = point(px, py)
  56.                         r = _red(z)
  57.                         g = _green(z)
  58.                         b = _blue(z)
  59.  
  60.                         c = cos((2*u + 1)*x*pi/(2*n)) * cos((2*v + 1)*y*pi/(2*n))
  61.  
  62.                         sr = sr + r*c
  63.                         sg = sg + g*c
  64.                         sb = sb + b*c
  65.                 next
  66.                 next
  67.  
  68.                 if x = 0 then cu = 1/sqr(2) else cu = 1
  69.                 if y = 0 then cv = 1/sqr(2) else cv = 1
  70.  
  71.                 dct(x0 + x, y0 + y).r = sr*cu*cv/(0.5*n)
  72.                 dct(x0 + x, y0 + y).g = sg*cu*cv/(0.5*n)
  73.                 dct(x0 + x, y0 + y).b = sb*cu*cv/(0.5*n)
  74.         next
  75.         next
  76.  
  77. 'quantization
  78. dim minr as double, ming as double, minb as double
  79. dim maxr as double, maxg as double, maxb as double
  80.  
  81. minr = 1000000
  82. ming = 1000000
  83. minb = 1000000
  84.  
  85. maxr = -1000000
  86. maxg = -1000000
  87. maxb = -1000000
  88.  
  89. for y=0 to hh
  90. for x=0 to ww
  91.         if dct(x, y).r < minr then minr = dct(x, y).r
  92.         if dct(x, y).g < ming then ming = dct(x, y).g
  93.         if dct(x, y).b < minb then minb = dct(x, y).b
  94.  
  95.         if dct(x, y).r > maxr then maxr = dct(x, y).r
  96.         if dct(x, y).g > maxg then maxg = dct(x, y).g
  97.         if dct(x, y).b > maxb then maxb = dct(x, y).b
  98.  
  99. _dest img1_dct
  100. for y=0 to hh
  101. for x=0 to ww
  102.         r = q(x, y).r
  103.         g = q(x, y).g
  104.         b = q(x, y).b
  105.  
  106.         pset (x, y), _rgb(r, g, b)
  107.  
  108.  
  109. _dest img1_dct
  110. for y=0 to hh
  111. for x=0 to ww
  112.         q(x, y).r = 255*(dct(x,y).r - minr)/(maxr - minr)
  113.         q(x, y).g = 255*(dct(x,y).g - ming)/(maxg - ming)
  114.         q(x, y).b = 255*(dct(x,y).b - minb)/(maxb - minb)
  115.  
  116.         r = q(x, y).r
  117.         g = q(x, y).g
  118.         b = q(x, y).b
  119.  
  120.         pset (x, y), _rgb(r, g, b)
  121.  
  122.  
  123. _dest img2_dct
  124. for y0=0 to hh-1 step n
  125. for x0=0 to ww-1 step n
  126.         for y=0 to 7 'n-1
  127.         for x=0 to 7 'n-1
  128.                 r = q(x0 + x, y0 + y).r
  129.                 g = q(x0 + x, y0 + y).g
  130.                 b = q(x0 + x, y0 + y).b
  131.  
  132.                 if (x0 + x < w) and (y0 + y < h) then pset (x0 + x, y0 + y), _rgb(r, g, b)
  133.         next
  134.         next
  135.  
  136. _dest img3_dct
  137. for y0=0 to hh-1 step n
  138. for x0=0 to ww-1 step n
  139.         for y=0 to 2 'n-1
  140.         for x=0 to 2 'n-1
  141.                 r = q(x0 + x, y0 + y).r
  142.                 g = q(x0 + x, y0 + y).g
  143.                 b = q(x0 + x, y0 + y).b
  144.  
  145.                 if (x0 + x < w) and (y0 + y < h) then pset (x0 + x, y0 + y), _rgb(r, g, b)
  146.         next
  147.         next
  148.  
  149. _dest img2
  150. 'inverse DCT
  151. for y0=0 to hh-1 step n
  152. for x0=0 to ww-1 step n
  153.         for y=0 to n-1
  154.         for x=0 to n-1
  155.                 sr = 0
  156.                 sg = 0
  157.                 sb = 0
  158.  
  159.                 for v=0 to 7 'n-1
  160.                 for u=0 to 7 'n-1
  161.                         c = cos((2*x + 1)*u*pi/(2*n))*cos((2*y + 1)*v*pi/(2*n))
  162.  
  163.                         if u = 0 then cu = 1/sqr(2) else cu = 1
  164.                         if v = 0 then cv = 1/sqr(2) else cv = 1
  165.  
  166.                         'sr = sr + dct(x + x3, y + y3).r*c*cu*cv
  167.                         'sg = sg + dct(x + x3, y + y3).g*c*cu*cv
  168.                         'sb = sb + dct(x + x3, y + y3).b*c*cu*cv
  169.  
  170.                         r = q(x0 + u, y0 + v).r
  171.                         g =     q(x0 + u, y0 + v).g
  172.                         b = q(x0 + u, y0 + v).b
  173.  
  174.                         sr = sr + c*cu*cv*((r/255)*(maxr - minr) + minr)
  175.                         sg = sg + c*cu*cv*((g/255)*(maxg - ming) + ming)
  176.                         sb = sb + c*cu*cv*((b/255)*(maxb - minb) + minb)
  177.                 next
  178.                 next
  179.  
  180.                 sr = sr/(0.5*n)
  181.                 sg = sg/(0.5*n)
  182.                 sb = sb/(0.5*n)
  183.  
  184.                 if (x0 + x < w) and (y0 + y < h) then pset (x0 + x, y0 + y), _rgb(sr, sg, sb)
  185.         next
  186.         next
  187.  
  188. _dest img3
  189. 'inverse DCT
  190. for y0=0 to hh-1 step n
  191. for x0=0 to ww-1 step n
  192.         for y=0 to n-1
  193.         for x=0 to n-1
  194.                 sr = 0
  195.                 sg = 0
  196.                 sb = 0
  197.  
  198.                 for v=0 to 2
  199.                 for u=0 to 2
  200.                         c = cos((2*x + 1)*u*pi/(2*n))*cos((2*y + 1)*v*pi/(2*n))
  201.  
  202.                         if u = 0 then cu = 1/sqr(2) else cu = 1
  203.                         if v = 0 then cv = 1/sqr(2) else cv = 1
  204.  
  205.                         'sr = sr + dct(x + x3, y + y3).r*c*cu*cv
  206.                         'sg = sg + dct(x + x3, y + y3).g*c*cu*cv
  207.                         'sb = sb + dct(x + x3, y + y3).b*c*cu*cv
  208.  
  209.                         r = q(x0 + u, y0 + v).r
  210.                         g = q(x0 + u, y0 + v).g
  211.                         b = q(x0 + u, y0 + v).b
  212.  
  213.                         sr = sr + c*cu*cv*((r/255)*(maxr - minr) + minr)
  214.                         sg = sg + c*cu*cv*((g/255)*(maxg - ming) + ming)
  215.                         sb = sb + c*cu*cv*((b/255)*(maxb - minb) + minb)
  216.                 next
  217.                 next
  218.  
  219.                 sr = sr/(0.5*n)
  220.                 sg = sg/(0.5*n)
  221.                 sb = sb/(0.5*n)
  222.  
  223.                 if (x0 + x < w) and (y0 + y < h) then pset (x0 + x, y0 + y), _rgb(sr, sg, sb)
  224.         next
  225.         next
  226.  
  227.  
  228. _putimage (w,0), img2
  229. _putimage (2*w,0), img3
  230. _putimage (0,h), img1_dct
  231. _putimage (w,h), img2_dct
  232. _putimage (2*w,h), img3_dct
  233.  
  234.  
dctc2.png
* dctc2.png (Filesize: 1.38 MB, Dimensions: 1919x852, Views: 450)
« Last Edit: July 02, 2018, 10:35:02 am by odin »

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Cosine Transform
« Reply #8 on: July 02, 2018, 03:14:44 am »
Out of interest, in this image I filtered out the lower frequencies rather than high frequencies and enhanced the otherwise very faint colors.  This highlights the information about the image lost in the above compression schemes.
dctc3.png
* dctc3.png (Filesize: 1.15 MB, Dimensions: 1280x852, Views: 478)

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Cosine Transform
« Reply #9 on: July 02, 2018, 12:09:50 pm »
Thank you very much, V. I muss to study :-D