Lazarus

Programming => Graphics and Multimedia => Audio and Video => Topic started by: mpknap on June 07, 2018, 04:08:48 pm

Title: Webcam OPENCV
Post by: mpknap on June 07, 2018, 04:08:48 pm
How to display the image from webcam on Panel1 or image1?

I use SendMessage (idResultado, WM_CAP_EDIT_COPY, 0, 0);
   
but this blocks the clipboard and you can not use CTRL + C during the process.

Title: Re: Webcam
Post by: bobix on June 07, 2018, 04:26:35 pm
Try something like this:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.GetPicture(OutputStream : TMemoryStream);
  2. var
  3.    BitmapImage : TBitmap;
  4.    JPEGImage   : TJPEGImage;
  5.    PictureFile : String;
  6. begin
  7.      if hWndC <> 0 then
  8.      begin
  9.           PictureFile := 'snapshot.bmp';
  10.           // grab frame
  11.           SendMessage( hWndC, WM_CAP_GRAB_FRAME, 0, 0);
  12.           // save bmp
  13.           SendMessage( hWndC,
  14.                        WM_CAP_SAVEDIB,
  15.                        0,
  16.                        longint(pchar(PictureFile)));
  17.  
  18.      end
  19.      else
  20.      begin
  21.           // a bitmap for a case you cannot grab a frame
  22.           PictureFile := 'webcamtrouble.bmp';
  23.      end;
  24.  
  25.      BitmapImage := TBitmap.Create;
  26.      with BitmapImage, BitmapImage.Canvas do
  27.      begin
  28.           LoadFromFile(PictureFile);
  29.           // date and time
  30.           TextOut(10, 10, DateToStr(Now)
  31.                           + '  '
  32.                           + TimeToStr(Now)
  33.                           + ' EMT');
  34.           // a message
  35.           TextOut(10, 30, ' ' + Edit1.Text + ' ');
  36.           Edit1.Text := ''; // message sent
  37.      end;
  38.  
  39.      { Assign bitmap to jpeg }
  40.      JPEGImage := TJPEGImage.Create;
  41.      with JPEGImage do
  42.      begin
  43.           Assign(BitmapImage);
  44.           CompressionQuality := 50;
  45.           SaveToStream(OutputStream);
  46.           Free;
  47.      end;
  48.  
  49.      BitmapImage.Free;
  50. end;            
  51.  
Title: Re: Webcam
Post by: mpknap on June 07, 2018, 04:42:59 pm
Thanks. I do not mean to write to a file. I will write what I want to do.

I display the frame from the webcam on the tpanel. (This is the Dark Frame. The camera is covered.) The tpanel image is analyzed by the Scanline function in search of a bright point. After analysis, the next frame is displayed and analyzed. And so 24 hours a day. ;). I am looking for a faster method than I have and without using a clipboard.
Title: Re: Webcam
Post by: marcov on June 07, 2018, 04:57:21 pm
This depends on the camera.  When I had a similar problem a decade ago I found out that the webcam api had two modus:

- single shot (for taking fotos for e.g. profile)
- video  (for video conferencing/skype  etc)

Now, the video mode is nearly always useless, it is a compressed stream, and fine details are killed by the compression anyway. The single shot (or other modes with compression off) had really low framerates (like 1 or 2 /s)

So I checked all the webcams my friends had, and settled on the eyetoy (the webcam from sony that belonged to the playstation 2).  It could do single shots at sufficient high rates (like 8 or 10/s)

My old codebase is here (http://www.stack.nl/~marcov/stackcamgl.zip), but it is mostly for a Windows XP era.

I still make vision apps, but nowadays only with commercial cameras, I gave up the webcam business (and thus haven't tested recent ones)
Title: Re: Webcam
Post by: mpknap on June 07, 2018, 09:16:58 pm
My old codebase is here, but it is mostly for a Windows XP era.


Can you convert it to the Lazarus version?
Title: Re: Webcam
Post by: Jurassic Pork on June 07, 2018, 11:42:52 pm
hello,
I display the frame from the webcam on the tpanel. (This is the Dark Frame. The camera is covered.) The tpanel image is analyzed by the Scanline function in search of a bright point. After analysis, the next frame is displayed and analyzed. And so 24 hours a day. ;). I am looking for a faster method than I have and without using a clipboard.
For a fast detection may be you can try to use opencv. For a starting point to use opencv with lazarus you can see here (https://forum.lazarus.freepascal.org/index.php/topic,31851.0.html?PHPSESSID=3q9m3s4auc25nlhprrmbv48an1).
Opencv can read  and analyze images from webcam.
Simple Brightness Tracking with OpenCV in Processing (https://vimeo.com/69805961)

in Attachments screenshot of lkdemo with Lazarus 1.8.2  32 bits on Windows 10 - OpenCV 3.0.0  . Video source : file.
Friendly, J.P
Title: Re: Webcam
Post by: mpknap on June 11, 2018, 06:49:09 am

OpenCV has solved the clipboard problem. I have transformed LKDEMO and it works quickly. There is not much about OPENCV and Pascal on the net, and I do not understand C ++ or Python, it's hard for me to move forward. Below is the LKDEMO code after the change. Why, when I cover the camera, the speed decreases very much? My project is based on working with a covered camera.

Second question, is OPENCV the function of calculating the brightness of each pixel and calculating the average for one frame? I do this with the ScanLine function.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode delphi}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   {$ifdef MSWINDOWS}Windows, unGetWinVersion,
  9.  {$endif}
  10.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,
  11.   StdCtrls, Spin, ExtCtrls,
  12.  
  13.    ipl, opencv;
  14.  const
  15.     MAX_COUNT = 500;
  16.  type
  17.   PRGB32Array = ^TRGB32Array;
  18.   TRGB32Array = packed array[0..MaxInt div SizeOf(TRGBQuad) - 1] of TRGBQuad;
  19.  
  20.  type
  21.  
  22.   { TForm1 }
  23.  
  24.   TForm1 = class(TForm)
  25.     Abort: TButton;
  26.     Image2: TImage;
  27.     Label2: TLabel;
  28.     Label3: TLabel;
  29.     Label4: TLabel;
  30.     Label5: TLabel;
  31.     VideoSettings: TButton;
  32.     AutoInit: TButton;
  33.     DeletePoints: TButton;
  34.     Night: TButton;
  35.     FrameRate: TFloatSpinEdit;
  36.     Image1: TImage;
  37.     Label1: TLabel;
  38.     Timer1: TTimer;
  39.     procedure AbortClick(Sender: TObject);
  40.     procedure AutoInitClick(Sender: TObject);
  41.     procedure DeletePointsClick(Sender: TObject);
  42.     procedure FormCreate(Sender: TObject);
  43.     procedure FormDestroy(Sender: TObject);
  44.     procedure FrameRateChange(Sender: TObject);
  45.     procedure NightClick(Sender: TObject);
  46.     procedure Timer1Timer(Sender: TObject);
  47.     procedure VideoSettingsClick(Sender: TObject);
  48.   private
  49.     { private declarations }
  50.   public
  51.     { public declarations }
  52.   end;
  53.  
  54.   TPointsArr = array[0..MAX_COUNT] of CvPoint2D32f;
  55.   PPointsArr = ^TPointsArr;
  56.  
  57. var
  58.   Counter :integer;
  59.   kalib  :double;
  60.   Form1: TForm1;
  61.   image: pIplImage = nil;
  62. grey: pIplImage = nil;
  63. image1: pIplImage = nil;
  64. grey1: pIplImage = nil;
  65. prev_grey: pIplImage = nil;
  66. pyramid: pIplImage = nil;
  67. prev_pyramid: pIplImage = nil;
  68. swap_temp: pIplImage;
  69.  
  70. win_size: longint = 10;
  71.  
  72. points: array[0..1] of PPointsArr;
  73. pointsRow1, pointsRow2: TPointsArr;
  74. swap_points: PCvPoint2D32f ;
  75. status: array [0..MAX_COUNT] of char;
  76. count: longint = 0;
  77. need_to_init: longint = 0;
  78. night_mode: longint = 0;
  79. flags: longint = 0;
  80. add_remove_pt: longint = 0;
  81. pt: CvPoint ;
  82.  
  83. nframe: integer;
  84.  
  85. i, k, c: longint;
  86. {-----------------------}
  87.  
  88. capture1,capture: PCvCapture;
  89. frame1,frame: PIplImage;
  90. cframe: integer = 0;
  91. selcam: longint = 0;
  92. color: CvScalar;
  93. bmp,bmp1: TBitmap;
  94.  
  95. implementation
  96.  
  97. {$R *.lfm}
  98.  
  99. procedure main_cycle();
  100. var
  101. cs: CvSize;
  102. eig, temp: PIplImage;
  103. quality, min_distance, dx, dy: double;
  104. i: integer;
  105. newpoint: PCvPoint2D32f;
  106.  frame: PIplImage;
  107.    ,img     : pIplImage;
  108.    x,y,w,h,ii, total: Integer;
  109.   szary, najjasniejszy : double;
  110.   sl: PRGB32Array;
  111.  
  112. begin
  113.  
  114.          frame := cvQueryFrame( capture );
  115.           if not (assigned(frame)) then
  116.             exit;
  117.  
  118.  
  119.         if not (assigned(image )) then
  120.         begin
  121.             //* allocate all the buffers
  122.             cs.width := frame.Width;
  123.             cs.height := frame.Height;
  124.             image := cvCreateImage( cs, 8, 3 );
  125.         //    image.Origin := frame.origin;
  126.         //        grey := cvCreateImage( cs, 8, 1 );
  127.         //  prev_grey := cvCreateImage( cs, 4, 1 );
  128.  
  129.  
  130.             flags := 0;
  131.         end;
  132.      
  133.         cvCopy( frame, image, 0 );
  134.        cvCvtColor( image, grey, CV_BGR2GRAY );
  135.      
  136.   inc(Counter);
  137.  form1.Label5.Caption:=inttostr(Counter);
  138.  
  139.         if( night_mode = 1) then
  140.             cvZero( image );
  141.        
  142.  
  143.         {visualize the camera image in the window}
  144.  
  145.         IplImage2Bitmap(image, bmp);
  146.       Form1.Image1.Picture.bitmap.assign(bmp);
  147.    
  148.      {  najjasniejszy := 0;
  149.         w := form1.image1.Width;
  150.         h := form1.image1.Height;
  151.  
  152.       for y := 1 to h - 1 do
  153.         begin
  154.           sl :=  form1.image1.Picture.Bitmap.ScanLine[y];
  155.           for x := 1 to w - 1 do
  156.             with sl[x] do
  157.             begin
  158.               szary := (rgbBlue + rgbGreen + rgbRed);
  159.               if szary > KALIBRACJA then
  160.                 KALIBRACJA := szary;
  161.             end;
  162.         end;}
  163.  
  164.         form1.Label2.Caption:=floattostr(szary);
  165.        
  166.  
  167. end;
  168.  
  169. { TForm1 }
  170.  
  171. procedure TForm1.FormCreate(Sender: TObject);
  172. var
  173.         nselCam, parm, n: longint;                                
  174. begin
  175.      
  176.     try
  177.        {$ifdef MSWINDOWS}  CorrectDSPackForVista; {$endif}
  178.         capture := cvCaptureFromCAM(0);
  179.      except
  180.         on ex : exception  do
  181.         begin
  182.                 ShowMessage('Start capturing error - '+ex.message);
  183.                 halt;
  184.         end;
  185.     end;
  186.     if not(assigned(capture ))  then
  187.     begin
  188.         ShowMessage('Could not initialize capturing from camera!!');
  189.         halt;
  190.     end;
  191.  
  192.     cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640);
  193.     cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
  194.  
  195.  
  196.     bmp := TBitmap.Create;
  197.      
  198.  
  199.     //fsetup := tsetupfo.create(self);
  200.     //fsetup.hide;
  201.     //fsetup.brightness := round(cvGetCaptureProperty(capture, CV_CAP_PROP_BRIGHTNESS));
  202.     //fsetup.contrast := round(cvGetCaptureProperty(capture, CV_CAP_PROP_CONTRAST));
  203.     //fsetup.saturation := round(cvGetCaptureProperty(capture, CV_CAP_PROP_SATURATION));
  204.  
  205.     nframe := 0;
  206.     timer1.enabled := true;
  207.  
  208. end;
  209.  
  210. procedure TForm1.AutoInitClick(Sender: TObject);
  211. begin
  212.    need_to_init := 1;
  213. end;
  214.  
  215. procedure TForm1.AbortClick(Sender: TObject);
  216. begin
  217.             self.Destroy;
  218.             halt;
  219. end;
  220.  
  221. procedure TForm1.DeletePointsClick(Sender: TObject);
  222. begin
  223.    count := 0;
  224. end;
  225.  
  226. procedure TForm1.FormDestroy(Sender: TObject);
  227. begin
  228.      cvReleaseCapture( @capture );
  229.      
  230. end;
  231.  
  232. procedure TForm1.FrameRateChange(Sender: TObject);
  233. begin
  234.   Timer1.Interval :=  Round(1000/FrameRate.Value);
  235. end;
  236.  
  237.  
  238.  
  239.  
  240.  
  241. procedure TForm1.NightClick(Sender: TObject);
  242. begin
  243.       night_mode := night_mode xor 1;
  244. end;
  245.  
  246. procedure TForm1.Timer1Timer(Sender: TObject);
  247. begin
  248.          inc(nframe);
  249. //        if (nframe>=seInterval.Value) then
  250.         begin
  251.                 nframe := 1;
  252.                 main_cycle;
  253.         end;
  254.         application.processMessages;
  255. end;
  256.  
  257. procedure TForm1.VideoSettingsClick(Sender: TObject);
  258. begin
  259.  
  260. end;
  261.  
  262.  
  263.  
  264. end.
  265.  
Title: Re: Webcam
Post by: Jurassic Pork on June 11, 2018, 07:30:20 am
hello,
you can try to use something like this (cvMinMaxloc function)  to find the darkest et brightest pixels of an image and display the max, min values and coordinates in a status bar :
Code: Pascal  [Select][+][-]
  1.  
  2. // new variables
  3. var     minval,maxval : double;
  4. minloc,maxloc : CvPoint;    
  5. //  
  6.  
  7.         cvCopy( frame, image, 0 );
  8.         cvCvtColor( image, grey, CV_BGR2GRAY );
  9.         cvMinMaxLoc(grey, @minval, @maxval,minloc,maxloc);
  10.         Form1.StatusBar1.SimpleText := 'Max : val= ' + floattostr(maxval) +
  11.         ' - loc= (' + inttostr(maxloc.x) + ',' +  inttostr(maxloc.y) + ')' +
  12.         '   ||   Min : val= ' + floattostr(minval) +
  13.         ' - loc= (' + inttostr(minloc.x) + ',' +  inttostr(minloc.y) + ')';  

Result in attachment.

Friendly, J.P
Title: Re: Webcam
Post by: mpknap on June 11, 2018, 02:18:03 pm
Thanks to J.P. Everything works .
But I still do not understand why the camera speed decreases when the lens is covered. I care about speed.
Title: Re: Webcam
Post by: marcov on June 11, 2018, 02:58:35 pm
Thanks to J.P. Everything works .
But I still do not understand why the camera speed decreases when the lens is covered. I care about speed.

So called Auto exposure. It gets darker, so the camera automatically ups the exposure time, thus limiting the framerates in low lighting conditions. This is a default for many cameras that you can often turn off.
Title: Re: Webcam
Post by: mpknap on June 11, 2018, 06:12:14 pm
Thank you. Yes, it's the time of exposure. Unfortunately I do not find a function to disable CAP_PROP_AUTO_EXPOSURE ( this is not in OPENCV.PAS). But I turned off the autoexposure in the external program and achieved space velocity;)
Title: Re: Webcam OPENCV
Post by: mpknap on June 12, 2018, 08:11:57 pm
One more question. Is it possible to connect with a DSLR or PS3Eye camera in Pascal and OpenCV ?
Title: Re: Webcam OPENCV
Post by: mpknap on October 27, 2018, 12:49:30 pm
And how to count how many pixels are brighter than some value?
Title: Re: Webcam OPENCV
Post by: Edson on October 27, 2018, 11:46:35 pm
I think you just need to compare the (RR+GG+BB) of the pixels and compare with the value.
Title: Re: Webcam OPENCV
Post by: lucamar on October 28, 2018, 12:52:55 am
And how to count how many pixels are brighter than some value?

That quite depends on what you consider--and how you calculate--"brightness", but unless it's some simple measure which can be compared directly to an (A)RGB value you'll have to get each pixel, convert its (A)RGB value to "brightness" and then check whether it's above, equal or below your reference, increasing the proper acumulator in each case.

Recomended reading: Lightness (https://en.wikipedia.org/wiki/Lightness), HSL and HSV (https://en.wikipedia.org/wiki/HSL_and_HSV) (Wikipedia)
Title: Re: Webcam OPENCV
Post by: mpknap on October 28, 2018, 07:49:46 am
   
I use: cvMinMaxLoc (image, @minval, @maxval, minloc, maxloc);   to find @maxval coordinates, but I want to count how many pixels are brighter than the RGB color 80:80:80.
Title: Re: Webcam OPENCV
Post by: Edson on January 07, 2019, 07:13:40 pm
I followed all the steps mentioned in the forum how to show the image of the webcam in Panel1 or image1 but I can not get it to show, I do not know if they could give me another solution ... I'm desperate!
Maybe you can use my library: https://github.com/t-edson/LazarusOpenCV
TinyPortal © 2005-2018