Image noise

From Rosetta Code
Revision as of 12:18, 2 October 2010 by Rdm (talk | contribs) (J: fps notes)
Task
Image noise
You are encouraged to solve this task according to the task description, using any language you may know.

Generate a random black and white 320x240 image continuously, showing FPS (frames per second).

Sample image:


C#

Max 185 FPS on .NET 4.0/Windows 7 64-bit on Athlon II X4 620 - ATI Radeon X1200.

<lang csharp>using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Runtime.InteropServices; using System.Windows.Forms;

class Program {

   static Size size = new Size(320, 240);
   static Rectangle rectsize = new Rectangle(new Point(0, 0), size);
   static int numpixels = size.Width * size.Height;
   static int numbytes = numpixels * 3;
   static PictureBox pb;
   static BackgroundWorker worker;
   static double time = 0;
   static double frames = 0;
   static Random rand = new Random();
   static byte tmp;
   static byte white = 255;
   static byte black = 0;
   static int halfmax = int.MaxValue / 2; // more voodoo! calling Next() is faster than Next(2)!
   static IEnumerable<byte> YieldVodoo()
   {
       // Yield 3 times same number (i.e 255 255 255) for numpixels times. 
       for (int i = 0; i < numpixels; i++)
       {
           tmp = rand.Next() < halfmax ? black : white; // no more lists!  
           // no more loops! yield! yield! yield!
           yield return tmp;
           yield return tmp;
           yield return tmp;
       }
   }
   static Image Randimg()
   {
       // Low-level bitmaps  
       var bitmap = new Bitmap(size.Width, size.Height);
       var data = bitmap.LockBits(rectsize, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
       Marshal.Copy(
           YieldVodoo().ToArray<byte>(),// source
           0, // start
           data.Scan0, // scan0 is a pointer to low-level bitmap data
           numbytes); // number of bytes in source
       bitmap.UnlockBits(data);
       return bitmap;
   }
   [STAThread]
   static void Main()
   {
       var form = new Form();
       form.AutoSize = true;
       form.Size = new Size(0, 0);
       form.Text = "Test";
       form.FormClosed += delegate
       {
           Application.Exit();
       };
       worker = new BackgroundWorker();
       worker.DoWork += delegate
       {
           System.Threading.Thread.Sleep(500); // remove try/catch, just wait a bit before looping
           while (true)
           {
               var a = DateTime.Now;
               pb.Image = Randimg();
               var b = DateTime.Now;
               time += (b - a).TotalSeconds;
               frames += 1;
               if (frames == 30)
               {
                   Console.WriteLine("{0} frames in {1:0.000} seconds. ({2:0} FPS)", frames, time, frames / time);
                   time = 0;
                   frames = 0;
               }
           }
       };
       worker.RunWorkerAsync();
       FlowLayoutPanel flp = new FlowLayoutPanel();
       form.Controls.Add(flp);
       pb = new PictureBox();
       pb.Size = size;
       flp.AutoSize = true;
       flp.Controls.Add(pb);
       form.Show();
       Application.Run();
   }

}</lang>

Factor

Still learning Factor, my code may suck, please fix.

By some reason, FPS does not show during execution on Linux.


Max 2 FPS on Factor 0.94 x86-64/Windows 7 64-bits - Athlon II X4 620 - ATI Radeon X1200.

<lang factor>USING: namespaces ui ui.gadgets ui.gadgets.buttons ui.gadgets.tracks ui.gadgets.borders images images.viewer models timers accessors kernel sequences sequences.deep byte-vectors random calendar io math math.functions math.parser prettyprint debugger system ; FROM: models => change-model ;

IN: imagenoise

TUPLE: imgmodel < model content ; SYMBOL: dispimg SYMBOL: num SYMBOL: ttime

randimg ( -- img )
<image>
 { 320 240 } >>dim
 RGB >>component-order
 ubyte-components >>component-type
 dup dim>> product
 [ { 255 0 } random 3 swap <repetition> ] replicate flatten >byte-vector >>bitmap ;

randimg imgmodel new-model dispimg set-global 0 num set-global 0 ttime set-global

[

 now
 dispimg get-global
 [ drop randimg ] change-model
 num get-global 1 +
 num set-global

 now swap time- duration>seconds
 ttime get-global +  
 ttime set-global
 
 num get-global 10 <= 
  [ ]
  [
   num get-global 
   ttime get-global 
   [ / round number>string " FPS" append ] try print
   0 num set-global
   0 ttime set-global ] if  

] 1 nanoseconds every

[ vertical <track>

dispimg get-global <image-control> { 5 5 } <border> f track-add  
 
"Test" open-window

] with-ui</lang>

J

<lang j>coclass'example' (coinsert[require)'jzopengl'

P=: 0 : 0 pc p nosize; xywh 0 0 160 120;cc c isigraph opengl; pas 0 0;pcenter; rem form end;

pshow;
timer 1;

)

timestamp=: (6!:8) %~ 6!:9

create=:3 :0

 ogl=:conew'jzopengl'
 frames=:0
 start=: timestamp
 sys_timer_base_=: 1 :('p_c_paint_',(;coname),'_')
 wd P

)

p_run=: 3 : 0

 conew'example'

)

destroy=:3 :0

 end=:timestamp
 smoutput 'frames per second: ',":frames%end-start
 wd 'timer 0'
 destroy__ogl
 wd'pclose'
 codestroy

)

p_close=: destroy

p_c_paint=: 3 : 0

 rc__ogl
 glClear GL_COLOR_BUFFER_BIT
 glBegin GL_POINTS
   glVertex _1+2*16000 2?@$ 0
 glEnd
 show__ogl
 frames=:frames+1

)

p_run</lang>

The script auto-starts when run (that last line p_run'' is responsible for the auto-start.

Average FPS are displayed when the window is closed.

With this revision, on my laptop, I typically get in the range of 58..59 FPS, with a cpu load of about 3% (so I am probably limited by v-sync, and if I tuned my opengl drivers I perhaps could get significantly faster fps?).

PureBasic

<lang PureBasic>#filter=0.2  ; Filter parameter for the FPS-calculation

  1. UpdateFreq=100  ; How often to update the FPS-display

OpenWindow(0,400,300,320,240,"PureBasic") Define w=WindowWidth(0), h=WindowHeight(0) Define x, y, T, TOld, FloatingMedium.f, cnt InitSprite() OpenWindowedScreen(WindowID(0),0,0,w,h,1,0,0,#PB_Screen_NoSynchronization) Repeat

 StartDrawing(ScreenOutput())
 For y=0 To h-1
   For x=0 To w-1
     If Random(1)
       Plot(x,y,#Black)
     Else
       Plot(x,y,#White)
     EndIf
   Next
 Next
 StopDrawing()
 FlipBuffers()
 cnt+1
 If cnt>=#UpdateFreq
   cnt =0
   TOld=T
   T   =ElapsedMilliseconds()
   FloatingMedium*(1-#filter)+1000*#filter/(T-TOld)
   SetWindowTitle(0,"PureBasic: "+StrF(#UpdateFreq*FloatingMedium,2)+" FPS")
   Repeat ; Handle all events
     Event=WindowEvent()
     If Event=#PB_Event_CloseWindow
       End
     EndIf
   Until Not Event
 EndIf

ForEver</lang>

Python

Library: Tkinter
Library: PIL

Max 23 FPS on Python 2.7 (r27:82525 MSC v.1500 32 bit Intel), Windows 7 64-bit on Athlon II X4 620 - ATI Radeon X1200.

<lang python>import Tkinter import Image, ImageTk import random import time

size = (320,240) pixels = size[0] * size[1]

class App():

   def __init__(self, root):  
       self.root = root
       self.root.title("Test")
       
       self.img = Image.new("RGB",size)        
       self.label = Tkinter.Label(root)
       self.label.pack()
       self.time = 0.0
       self.frames = 0        
       self.loop() 
   def loop(self):
       self.ta = time.time()
       # 13 FPS boost. half integer idea from C#.
       self.img.putdata([(255,255,255) if random.random() > 0.5 else ( for i in range(pixels)])
       self.pimg = ImageTk.PhotoImage(self.img)
       self.label["image"] = self.pimg        
       self.tb = time.time()
       
       self.time += (self.tb - self.ta)
       self.frames += 1
       if self.frames == 30:
           try:
               self.fps = self.frames / self.time
           except:
               self.fps = "INSTANT"
           print "%d frames in %3.2f seconds (%s FPS)" % (self.frames, self.time, self.fps)
           self.time = 0
           self.frames = 0
     
       self.root.after(1, self.loop)

root = Tkinter.Tk() app = App(root) root.mainloop()</lang>

Tcl

Library: Tk

Please add FPS info.

<lang tcl>package require Tk

proc generate {img width height} {

   set data {}
   for {set i 0} {$i<$height} {incr i} {

set line {} for {set j 0} {$j<$width} {incr j} { lappend line [lindex "#000000 #FFFFFF" [expr {rand() < 0.5}]] } lappend data $line

   }
   $img put $data

}

set time 0.0 set count 0

proc looper {} {

   global time count
   set t [lindex [time {generate noise 320 240}] 0]
   set time [expr {$time + $t}]
   if {[incr count] >= 30} {

set time [expr {$time / 1000000.0}] set fps [expr {$count / $time}] puts [format "%d frames in %3.2f seconds (%f FPS)" $count $time $fps] set time 0.0 set count 0

   }
   after 1 looper

}

image create photo noise -width 320 -height 240 pack [label .l -image noise] update looper</lang>