Shop OBEX P1 Docs P2 Docs Learn Events
Using Parallax Laser Rangefinder as a camera. — Parallax Forums

Using Parallax Laser Rangefinder as a camera.

BeanBean Posts: 8,129
edited 2013-06-24 11:33 in Accessories
If I am reading the datasheet correctly the only image formats that can be obtained are:
160x128 8-bit grayscale
640x16 16-bit color (w/laser enabled)

I'm confused by the 640x16 color resolution.

Is there any way to get a high resolution (640x480) color image data from this ? Preferable with the laser disabled.
I would guess the camera can do it, but you need an NDA to get the datasheet.

Bean
«1

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-10-04 10:29
    Bean, where would you store 640x480x3 bytes of data if you could get that much from the sensor?

    -Phil
  • BeanBean Posts: 8,129
    edited 2011-10-04 10:33
    Phil,
    I don't know what the slowest clock speed is. But there are various propeller boards with additional SRAM on them that could be used.
    Initially I would like to do experiments by processing the image data "on-the-fly" again if the camera clock speed can be slowed down enough.
    Either way it would be a pretty good generic digital camera for any microcontroller if it just had the commands to get full-frame color data (even 160x128 8-bit color would be okay with me).

    Bean
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-10-04 11:00
    If I could get a color picture out of one of these, I think I'd purchase one.

    One should be able to look for color blobs without keeping the whole image in memory.

    I'd also like to try using it with one of the many external memory options.

    Having access to the color image would make this a more attractive product.

    Duane
  • ratronicratronic Posts: 1,451
    edited 2011-10-05 08:40
    Bean in the OVM7690_obj.spin seems to allow for some settings but I haven't even hooked a prop clip to mine to play yet.

    Edit: I have used it normally though!
     
    CON                                                                                                                                        
      OVM7690_Addr  = %0100_0010     ' SCCB/I2C address: corresponds to write address $42 and read address $43                                 
     
      CamXVCLKFreq  = 24_000_000     ' XVCLK frequency determines SCCB (Serial Camera Control Bus) speed, OVM7690 data sheet section 1.2.9     
     
      ' I/O pin connections to the Propeller                                                                                                   
      ' Others defined in OVM7690_fg                                                                                                           
      CamPWDN         = 8                                                                                                                      
      CamSDA          = 9                                                                                                                      
      CamSCL          = 10                                                                                                                     
      CamXVCLK        = 14                                                                                                                     
     
      ' Frame grab type                                                                                                                        
      GreySingle     = 0  ' single greyscale frame                                                                                             
      ColorSingle    = 1  ' single color frame                                                                                                 
      ColorRange     = 2  ' color frame grab specific for range finding:                                                                       
                          ' one with laser on, one with laser off, background subtraction for better detection of laser spot                   
                          ' details of pixel subtraction: [URL]http://homepages.inf.ed.ac.uk/rbf/HIPR2/pixsub.htm[/URL]                                   
     
      ' Results display type                                                                                                                   
      ResultASCII    = 0                                                                                                                       
      ResultBinary   = 1                                                                                                                       
    
  • BeanBean Posts: 8,129
    edited 2011-10-06 09:38
    Looking at the code I think it IS possible to get a full color 640x480 image.
    I have a LRF on order, just need to wait for it to arrive. I can't wait to start experimenting. Waahhh, haaa haaa, haa haa.

    Bean
  • ratronicratronic Posts: 1,451
    edited 2011-10-06 11:33
    At the top of that spin program it notes you have to sign a non disclosure agreement with Omnivision to obtain the data for that camara. But Joe has written some methods to set the resolution and different frame grabs for grey scale or color with the laser on or off.
  • BeanBean Posts: 8,129
    edited 2011-10-10 11:22
    I got the LRF sensor on Friday. Got around to playing with it today.

    The sensor is too fast to do any kind of processing on-the-fly. Pretty much you can just store the data.

    So I guess the question is would you rather have high-resolution and low bits per pixel, or low-resolution and high bits per pixel ?

    I'm thinking about trying 120x90 16-bits per pixel (5,6,5). That should be usable.

    Bean
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-10-10 12:11
    Bean,

    Do you have access to the high res color images?

    Even if just one frame at a time that can be stored to external memory.

    I'd like the option of having a high res color image that I could then look at (with a program on the Prop) and find color blobs etc.

    Can you capture a 640 x 480 (I think16-bit color would be good enough) image?

    The ability of access a high res color image is an important feature to me.

    Thanks for the update.

    Duane
  • BeanBean Posts: 8,129
    edited 2011-10-10 15:11
    Duane,
    The problem is that the camera supplies the pixel clock. The clock rate is 1MHz (I think, might be 500Khz), so it doesn't leave alot of time to do much processing.
    I don't have a C3 or other board with SRAM, so I don't know how it compares to HUB access in speed.
    There might be a way to slow down the pixel clock ? I don't know
    From what I've seen, you CAN get a 640x480 color image (8 bit Y, 8 bit U, 8 bit V). But you need a storage media that is fast enough to store it.

    Bean
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-10-10 15:52
    Bean,

    My thought is to have data passed directly to some SRAM. This seems like the problem a solution of eight parallel SRAM chips has been waiting for.

    The Prop could then leisurely look through the data for color blobs etc.

    Do you think this would be possible? (I wont hold you to it.)

    I'll likely buy one of these if you think this would work.

    Thanks for all the information so far.

    Duane
  • BeanBean Posts: 8,129
    edited 2011-10-10 18:24
    Duane,
    I'd say it is do-able. The code for the 640x16 frame grabber actually sets up the camera for 640x480, then skips the first 200+ lines to get to the middle 16 that it wants to store.

    WRBYTE is pretty slow, so external SRAM may not be too much slower (if any).

    Just to get familiar with the frame grabber code, I optimized it somewhat and perform the byte-swap "on the fly" so you don't need to do it at the end.

    I wish Joe would have made a simple camera board with some SRAM. I think it would have sold very well.

    Bean
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-10-10 19:26
    Thank you Bean.

    It's very nice to know all this ahead of time. I think I'll probably order one of these.

    Personally I thought it was priced a bit high. If you just want a rangefinder, I think a laser a Wii camera would likely do the job and be a lot less expensive.

    Having access to the camera image makes the Parallax Laser Rangefinder a much more useful product.

    Duane
  • BeanBean Posts: 8,129
    edited 2011-10-11 06:18
    Duane,
    I was wrong about the pixel rate, it is 2MHz.

    I have made changes to the firmware to allow a color capture of 120x85 pixel frame in the same format as the 640x16 frame (16-bit YUV422y1,u,y2,v]) by sending the character "Y".
    At the moment I don't have any way to seeing the image data.
    If I post the code would have the ability to test it ?

    Bean
  • ratronicratronic Posts: 1,451
    edited 2011-10-11 07:32
    Bean I am still unable to play with mine as I don't have a prop 'clip' only some prop 'plug's. But I plan on soldering a 4 pin header to mine and use prop plug instead of a prop clip. I also had been planning to use a uOLED-128-G1 to display portions of the data dumps. I'm not sure when I'll get this done. I'm off to google YUV422y1 now to see if I can get the uOLED to display that. Can you post your version of the firmware?
  • BeanBean Posts: 8,129
    edited 2011-10-11 07:52
    Sure here it is. It is setup to use pins 30 and 31, so if you want to use Sin and Sout pins you'll have to change it at the beginning of the main file "LRF_OVM7690_Modified.spin".
    Send it a "U" to setup the auto-baud.
    Send it a "Y" to request a full color frame (120 x 85 pixels).

    The pixels are send as pairs consisting of 4 bytes [y1,u,y2,v] so the same "u" and "v" values are used for both pixels y1 and y2 (which have the luma or grayscale value). All are 8-bits. "u" and "v" are signed.
    So each line is 240 bytes.

    A good starting point would be to display just the y1 and y2 as grayscale (ignoring "u" and "v").

    Bean
  • ratronicratronic Posts: 1,451
    edited 2011-10-11 08:07
    Is y1 an 8 bit grayscale by itself?
  • BeanBean Posts: 8,129
    edited 2011-10-11 08:18
    Yes, y1 and y2 are 8 bit grayscale values for the two pixels. You only need "U" and "V" if you want color.

    Bean
  • ratronicratronic Posts: 1,451
    edited 2011-10-11 08:34
    When you say two pixels I'm not sure what you mean. The uOLED can display a grayscale image with one byte per pixel?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-10-11 09:18
    Bean,

    I just looked through the code. It's amazingly well documented.

    I agree with you, if I can find a way of storing the data, I should be able to save a high res image.

    I was just looking at the schematic and the product photo. It looks like pins 16 - 23 aren't used and are brought out to solder pads (very nice). I think I'll use these pins for SRAM data lines and use the red and green LED pins for clock and chip select.

    Color blobs and world conquest here I come. (I just need to ask my wife first.)

    Duane
  • BeanBean Posts: 8,129
    edited 2011-10-11 09:19
    Dave,
    That is perfect, just ignore every second byte.

    The YUV422 protocol uses one "U" and one "V" value for each pair of consecutive pixels because intensity ("Y") is more important than color ("u" and "v") to the human eye.
    So four bytes represents two consecutive pixels

    Bean
  • ercoerco Posts: 20,244
    edited 2011-10-11 09:50
    That rangefinder is $129, right? Plus whatever hardware/processor you're using. Probably for a mobile robot app? Camera & blob tracking?

    A small Acer Asprire netbook or equivalent can be had for about $200, which has a built-in camera will run RoboRealm. You could make your own laser rangefinder; mount a small laser pointer and track the laser spot with the camera and computing using the parallax effect. Now you have a camera, imaging, plenty of processing power & apps. Mount it on a small mobile platform and it would be like a mini ER-1 from Evolution Robotics.
  • ratronicratronic Posts: 1,451
    edited 2011-10-11 11:01
    I had to dig up my uOLED as I just moved. I will get this hooked up and give it a try. My LRF is atop a moveable x,y platform on the back of my stingray with another camara.
  • BeanBean Posts: 8,129
    edited 2011-10-11 11:47
    I found a bug in my code. Here is the fixed version. The resolution has changed to 128x80.
    I also made a viewer (black and white threshold) using VGA on the Demo board just to make sure it was working.

    I cannot check the color bytes "U" and "V", so if someone with a color display could that would be great.

    Bean
  • ratronicratronic Posts: 1,451
    edited 2011-10-11 12:21
    Bean the uOLED actually has three bytes per pixel so for even for greyscale I would just set the same byte amount for each rgb pixel. I'm not quite sure how to translate the video formats but it will be great to even get a pix. Right now I'm having problems talking with the uOLED even running the demo program from Steve McManus. But when I get everything straightened out I will give your updated version of the firmware a shot.
  • BeanBean Posts: 8,129
    edited 2011-10-11 13:11
    Here is some info I found.
    Converting 8-bit YUV to RGB888
     
    The following coefficients are used in conversion process:
    
    C = Y - 16
    D = U - 128
    E = V - 128
    
     
    Using the previous coefficients and noting that clip() denotes clipping a value to the range of 0 to 255, the following formulas provide the conversion from YUV to RGB:
    
    R = clip(( 298 * C           + 409 * E + 128) >> 8)
    G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
    B = clip(( 298 * C + 516 * D           + 128) >> 8)
    

    Bean
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-10-11 15:37
    Bean,

    Thanks for sharing what you've found out. It really helped me to decide about purchasing the rangefinder or not. I ordered one today.

    I plan to make an 8-bit SRAM module to store images from the camera.

    I'd like to figure out how to display images (not necessarily high res) on Rayman's 4.3" displays. I think this is going to take several Propellers working together. I think I'll share the 8-bit SRAM bus with another Prop so it can read the images faster. I'll probably just have the LRF board store the image to SRAM and have a second Prop analyze and display the images.

    Thanks again Bean.

    Duane
  • ratronicratronic Posts: 1,451
    edited 2011-10-11 17:04
    After I installed your latest firmware I tried this on my PPDB and I find that the 'G' or your new 'Y' command does make the LRF respond but I am only getting back 1540 bytes with either command. So I'm not sure the serial buffer is keeping up? I will install the original firmware and work with it until I can get a greyscale pix on the uOLED and then come back and try again.
    Con                                                          
     
      _CLKMODE = XTAL1 + PLL16X                              
      _XINFREQ = 5_000_000  
      ack     = $06                                         ' Acknowledge byte      
      nak     = $15                                         ' Invalid command byte  
     
    Var
     
    Obj                                                      
      db : "pcfullduplexserial"
     
    Pub start| i,j,x,y                              
      db.init
      db.addport(0, 31, 30, -1, -1, 0, 0, 115200) 'debug port
      db.addport(1, 6, 7, -1, -1, 0, 0, 115200)  'camara
      db.addport(2, 4, 5, -1, -1, 0, 0, 115200) 'uoled 
      db.start
      waitcnt(clkfreq*3+cnt)
      db.rxflush(1)
      db.tx(1,"U")
      repeat until db.rx(1) == ":"
      db.rxflush(2)                              
      db.tx (2, "U")
      waitack
      waitcnt(1600000+cnt)
      erase
      db.str(0, string("uOLED ready",13))
      display
      repeat
     
    Pub waitack | temp                                                      
      repeat until db.rx(2) == ack
     
    Pub erase                                            
      db.tx (2, "E")    
      waitack
     
    Pub display | p, x, y
      db.tx(1, "G")
      repeat y from 0 to 127
        repeat x from 0 to 159
          if x < 128
            p := db.rx(1)
            plot(x, y, p, p, p)
          else
            db.rx(1)
    Pub plot(x, y, r, g, b)                                                 
      '     X : 0 to 127                              
      '     Y : 0 to 127                              
      '   Red : 0 to 255                              
      ' Green : 0 to 255                              
      '  Blue : 0 to 255                              
     
      r := r >> 3 << 11 | (g >> 2 << 5) | (b >> 3)    
      db.tx(2, "P")                                 
      db.tx(2, x)                                   
      db.tx(2, y)                                   
      db.tx(2, r.byte[1])                           
      db.tx(2, r.byte[0])                           
      waitack
    
  • BeanBean Posts: 8,129
    edited 2011-10-11 17:22
    Dave,
    Your plot routine is sending 5 bytes to the oLED for every byte recieved from the LRF.
    The input buffer from the LRF will surely overflow waiting for the oLED to send and ack each pixel.

    Try making the LRF baud rate much slower (like 19200 or 9600).

    Joe, if you are reading this...What is the chance of getting the windows viewer software to support 128x80 color frames ? Seems like there is a fair amount of interest in using the LRF as a camera.

    Bean
  • ratronicratronic Posts: 1,451
    edited 2011-10-11 18:31
    Using that serial object the slowest I can get the LRF to autobaud too is 57600 and I get 1988 bytes now. But the picture information is there, I will have to figure a different way to get at it maybe by downloading it first with fullduplexserial.spin then stop and restart the fds object for the uOLED and then dump the downloaded contents to the uOLED.
  • ratronicratronic Posts: 1,451
    edited 2011-10-11 19:38
    I finally received my first greyscale picture from my LRF on my uOLED!
    Edit: I updated the baud speed for the LRF and fixed the x plot range of the uOLED.
    Con                                                         
     
      _CLKMODE = XTAL1 + PLL16X                              
      _XINFREQ = 5_000_000  
      ack     = $06                                         ' Acknowledge byte      
      nak     = $15                                         ' Invalid command byte  
     
    Var
      byte buffer[20480]
     
    Obj                                                      
      db : "pcfullduplexserial"
      fd : "fullduplexserial"  
    Pub start| i,j,x,y
      fd.start(6, 7, 0, 115200)                             '
      db.init                                                
      db.addport(0, 31, 30, -1, -1, 0, 0, 115200) 'debug port 
      'db.addport(1, 6, 7, -1, -1, 0, 0, 57600)  'camara      
      db.addport(2, 4, 5, -1, -1, 0, 0, 115200) 'uoled       
      db.start                                               
      waitcnt(clkfreq*3+cnt)
      fd.rxflush
      fd.tx("U")
      repeat until fd.rx == ":"
      db.str(0, string("Camara online",13))
      db.rxflush(2)                              
      db.tx (2, "U")
      waitack
      waitcnt(1600000+cnt)
      erase
      db.str(0, string("uOLED ready",13))
      get
      display
      repeat   
     
    Pub waitack | temp                                                      
      repeat until db.rx(2) == ack
     
    Pub erase                                            
      db.tx (2, "E")    
      waitack
     
    Pub get | p, x, y
      fd.tx("G")
      x := 0
      y := 0
      repeat y from 0 to 127
        repeat x from 0 to 159
          p := fd.rx
          buffer[(y*160)+x] := p
    Pub display | p, x, y
      repeat y from 0 to 127
        repeat x from 0 to 159
          if x < 128
            p := buffer[(y*160)+x]
            plot(x,y,p,p,p)      
     
    Pub plot(x, y, r, g, b)                                                 
      '     X : 0 to 127                              
      '     Y : 0 to 127                              
      '   Red : 0 to 255                              
      ' Green : 0 to 255                              
      '  Blue : 0 to 255                              
     
      r := r >> 3 << 11 | (g >> 2 << 5) | (b >> 3)    
      db.tx(2, "P")                                 
      db.tx(2, x)                                   
      db.tx(2, y)                                   
      db.tx(2, r.byte[1])                           
      db.tx(2, r.byte[0])                           
      waitack
    
Sign In or Register to comment.