Recent

Author Topic: [Solved] Image capture from webcam to jpg.  (Read 1737 times)

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
[Solved] Image capture from webcam to jpg.
« on: November 23, 2020, 08:51:25 pm »
Hello, I making a program that connects to a usb webcam using videodev2 that I get from sdpo package.
I have any problem to capture a frame. But I want to save it as jpg format.

Code: [Select]
repeat
    begin
      FillChar(vBuf, sizeof(v4l2_buffer), 0);
      vbuf._type := V4L2_BUF_TYPE_VIDEO_CAPTURE;
      vbuf.memory := V4L2_MEMORY_MMAP;
      //Capturar imagen
      if DynIoctl(videohandle, VIDIOC_DQBUF, @vbuf) < 0 then
      begin
        raise Exception.Create('Fallo durante la captura');
      end;
    end;

  until vBuf.bytesused > 0;
  VideoBufferIndex := vbuf.index;
  FramePtr := VideoBuffer[VideoBufferIndex];

  Datos := TMemoryStream.Create;
  Datos.SetSize(vHeight * vWidth);
  Datos.Position := 0;
  size := vHeight * vWidth;

  //   case PixelFormat of
  //     uvcpf_YUYV:
  //YUYV_to_Gray  function converted
  for i := 0 to (size div 2) - 1 do
  begin
    g := FramePtr^ and $FF;
    r := g;
    b := g;
    //dest^ := (r shl 16) or (g shl 8) or (b);
    temp := (r shl 16) or (g shl 8) or (b);
    Datos.Write(temp, SizeOf(Temp));


    g := (FramePtr^ shr 16) and $FF;
    r := g;
    b := g;
    //dest^ := (r shl 16) or (g shl 8) or (b);
    temp := (r shl 16) or (g shl 8) or (b);
    Datos.Write(temp, SizeOf(Temp));
    Inc(FramePtr);
    //Inc(dest);
  end;
   
   Imagen := TFPMemoryImage.Create(vWidth,vHeight);
   Imagen.UsePalette:=true;
    MiPaleta.Alpha:=0;
   MiPaleta.Blue:=155;
   MiPaleta.Green:=75;
   MiPaleta.Red:=56;
   f := Imagen.Palette.Add(MiPaleta);
   DAtos.Position:=0;
   For X:= 0 To Imagen.Width-1 do
   begin
      For Y := 0 To Imagen.Height-1 do
      begin
        pixel := Datos.ReadByte;
        Imagen.Pixels[x,y] := pixel;
      end;
   end;

  //   case PixelFormat of
  //     uvcpf_YUYV:
  //       YUYV_to_Gray(PLongWord(FramePtr), (pdatos),
  //         vWidth * vHeight);
  //     uvcpf_YUV420:
  //       YUV420_to_Gray(FramePtr,  (pdatos), vWidth * vHeight);
  //     uvcpf_RGB24:
  //       RGB24_to_TrueColor(PRGB24Pixel(FramePtr),  (pdatos), vWidth * vHeight);
  //     uvcpf_BGR24:
  //       BGR24_to_TrueColor(PRGB24Pixel(FramePtr),  (pdatos), vWidth * vHeight);
  //   end;

     j := TFPWriterJPEG.Create;
     j.CompressionQuality:=75;
    Imagen.SaveToFile('pepe.jpg',j);
                                                                                         

In this code, I got a image from camera, and I convert to  YUYV_to_Gray and store into TMemorystream. But I'm lost with palette. I think I should create 255 palettes, which  values?. Or there is other way to do the job?.

I attach all code.
Programmed in Linux 20.04 and Lazarus 2.10

Thanks in advance

/BlueIcaro
« Last Edit: November 27, 2020, 05:54:56 pm by BlueIcaro »

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
Re: Image capture from webcam to jpg.
« Reply #1 on: November 23, 2020, 10:34:36 pm »
You can make a grayscale palette with a loop with i from 0 to 255, setting Red, Green and Blue to I*$0101 and alpha to $ffff
Conscience is the debugger of the mind

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: Image capture from webcam to jpg.
« Reply #2 on: November 24, 2020, 01:21:49 am »
hello,
if you have mplayer installed in your O.S and you  make a graphical program, have a look
 here  and here

Friendly, J.P
« Last Edit: November 24, 2020, 01:26:35 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Image capture from webcam to jpg.
« Reply #3 on: November 24, 2020, 06:40:14 pm »
hello,
if you have mplayer installed in your O.S and you  make a graphical program, have a look
 here  and here

Friendly, J.P

The program will run in a linux without GUI.

/BlueIcaro

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Image capture from webcam to jpg.
« Reply #4 on: November 25, 2020, 04:19:50 pm »
Hello, I make some changes in the program. I can save a jpeg image. But my image is not equal to original is like rotate and cutted.

This the code that I use to capture:
Code: Pascal  [Select][+][-]
  1.  
  2. procedure GuardarImagen;
  3.  
  4. var
  5.   vBuf: v4l2_buffer;
  6.   VideoBufferIndex: __u32;
  7.   FramePtr: PByte;
  8.   x, y, i, size, f: integer;
  9.   Datos: TMemoryStream;
  10.   Imagen: TFPMemoryImage;
  11.   MiPaleta: TFPColor;
  12.   j: TFPWriterJPEG;
  13.   Convertido, src: PRGB24Pixel;
  14.   Blue, Green, Red, g, r, b: byte;
  15.   h, by, pixel: longint;
  16.   d, RgbColor: longword;
  17.   buffer: TRGB24Pixel;
  18.   color: TColor;
  19.   dest: Pointer;
  20.  
  21. begin
  22.   repeat
  23.     begin
  24.       FillChar(vBuf, sizeof(v4l2_buffer), 0);
  25.       vbuf._type := V4L2_BUF_TYPE_VIDEO_CAPTURE;
  26.       vbuf.memory := V4L2_MEMORY_MMAP;
  27.       //Capturar imagen
  28.       if DynIoctl(videohandle, VIDIOC_DQBUF, @vbuf) < 0 then
  29.       begin
  30.         raise Exception.Create('Fallo durante la captura');
  31.       end;
  32.     end;
  33.  
  34.   until vBuf.bytesused > 0;
  35.   Sleep(2000);
  36.   VideoBufferIndex := vbuf.index;
  37.   FramePtr := VideoBuffer[VideoBufferIndex];
  38.  
  39.   Datos := TMemoryStream.Create;
  40.   //Datos.SetSize(vHeight * vWidth);
  41.   Datos.Position := 0;
  42.   size := vHeight * vWidth * 3;
  43.  
  44.   case PixelFormat of
  45.     uvcpf_YUYV:
  46.       writeln('uvcpf_YUYV');
  47.     uvcpf_YUV420:
  48.       writeln('uvcpf_YUV420');
  49.     uvcpf_RGB24:
  50.       writeln('uvcpf_RGB24');
  51.     uvcpf_BGR24:
  52.       WriteLn('uvcpf_BGR24');
  53.   end;
  54.  
  55.  
  56.   //convers format uvcpf_BGR24
  57.   src := PRGB24Pixel(FramePtr);
  58.   for I := 0 to size - 1 do
  59.   begin
  60.     RgbColor := PLongWord(@src[I])^;
  61.     datos.Write(RgbColor,1);
  62.   end;
  63.  
  64.   Imagen := TFPMemoryImage.Create(vWidth, vHeight);
  65.  
  66.   Imagen.UsePalette := True;
  67.   for I := 0 to 255 do
  68.   begin
  69.     MiPaleta.Alpha := $FFFF;
  70.     MiPaleta.Blue := I * $0101;
  71.     MiPaleta.Green := I * $0101;
  72.     MiPaleta.Red := I * $0101;
  73.  
  74.     f := Imagen.Palette.Add(MiPaleta);
  75.   end;
  76.  
  77.  
  78.  
  79.   Datos.Position := 0;
  80.   for X := 0 to Imagen.Width - 1 do
  81.   begin
  82.     for Y := 0 to Imagen.Height - 1 do
  83.     begin
  84.       Datos.Read(RgbColor,1);
  85.       Imagen.Pixels[x, y] := RgbColor;
  86.     end;
  87.   end;
  88.  
  89.  
  90.  
  91.   j := TFPWriterJPEG.Create;
  92.   j.CompressionQuality := 100;
  93.   Imagen.SaveToFile('pepe.jpg', j);
  94. end;
  95.          
  96. I attach the program complete. And two image. The "original" and the image that saves my program
  97.  
  98. Any Idea
  99. Thanks
  100. /BlueIcaro
  101.  
  102.  

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
Re: Image capture from webcam to jpg.
« Reply #5 on: November 25, 2020, 04:31:46 pm »
I suppose pixels are organized as rows, so:
Code: Pascal  [Select][+][-]
  1. Datos.Position := 0;
  2.   for Y := 0 to Imagen.Height - 1 do
  3.   begin
  4.     for X := 0 to Imagen.Width - 1 do
  5.     begin
  6.       Datos.Read(RgbColor,1);
  7.       Imagen.Pixels[x, y] := RgbColor;
  8.     end;
  9.   end;
Conscience is the debugger of the mind

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Image capture from webcam to jpg.
« Reply #6 on: November 25, 2020, 04:46:45 pm »
Amazing Circular!!!
I was fighting with Tmemoruimage, and the tstreammemory, because I thought that the problem was when the programs moved the info from image buffer.
Also I thought that the program leaved the repeat until loop before image was complete.
I spend this days reading about linux driver  (  https://linuxtv.org/docs.php )   %)

I didn't see that the rows are changed by cols  :-[

Two fast (i hope) questions more:
How can I make a palette with the colors?
Where Can I find more info about colors, palettes, etc?

Thanks

/BlueIcaro

P.D I attach the image with Circular solution. The image is not the same that the previous post, because I moved the camera.
« Last Edit: November 25, 2020, 04:49:22 pm by BlueIcaro »

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
Re: Image capture from webcam to jpg.
« Reply #7 on: November 25, 2020, 05:43:32 pm »
Basically you don't need to use the intermediate memory stream Datos nor Palette. You can set the RGB values directly:
Code: Pascal  [Select][+][-]
  1. var fpCol: TFPColor;
  2. ...
  3.   Imagen := TFPMemoryImage.Create(vWidth, vHeight);
  4.   src := PRGB24Pixel(FramePtr);
  5.   fpCol.alpha := $ffff;
  6.   for Y := 0 to Imagen.Height - 1 do
  7.     for X := 0 to Imagen.Width - 1 do
  8.     begin
  9.       fpCol.red := src^.red * $101;
  10.       fpCol.green := src^.green * $101;
  11.       fpCol.blue := src^.blue * $101;
  12.       Imagen.Colors[x, y] := fpCol;
  13.       inc(src);
  14.     end;
  15.   ...
  16.   Imagen.Free; // don't forget to free memory
Conscience is the debugger of the mind

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
(Solved) Image capture from webcam to jpg.
« Reply #8 on: November 26, 2020, 09:04:51 pm »
Thank you very match for all
/BlueIcaro

 

TinyPortal © 2005-2018