Recent

Author Topic: Webcam OPENCV  (Read 13352 times)

mpknap

  • Full Member
  • ***
  • Posts: 155
Webcam OPENCV
« 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.

« Last Edit: June 12, 2018, 08:10:22 pm by mpknap »

bobix

  • Jr. Member
  • **
  • Posts: 71
    • http://rechnik-bg.com
Re: Webcam
« Reply #1 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.  
Lazarus 1.8.4 r57972 FPC 3.0.4 i386-win32-win32/win64

mpknap

  • Full Member
  • ***
  • Posts: 155
Re: Webcam
« Reply #2 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.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Webcam
« Reply #3 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, 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)

mpknap

  • Full Member
  • ***
  • Posts: 155
Re: Webcam
« Reply #4 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?

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: Webcam
« Reply #5 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.
Opencv can read  and analyze images from webcam.
Simple Brightness Tracking with OpenCV in Processing

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
« Last Edit: June 08, 2018, 01:00:57 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

mpknap

  • Full Member
  • ***
  • Posts: 155
Re: Webcam
« Reply #6 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.  

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: Webcam
« Reply #7 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
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

mpknap

  • Full Member
  • ***
  • Posts: 155
Re: Webcam
« Reply #8 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.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Webcam
« Reply #9 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.

mpknap

  • Full Member
  • ***
  • Posts: 155
Re: Webcam
« Reply #10 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;)

mpknap

  • Full Member
  • ***
  • Posts: 155
Re: Webcam OPENCV
« Reply #11 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 ?
« Last Edit: September 24, 2018, 07:58:41 am by mpknap »

mpknap

  • Full Member
  • ***
  • Posts: 155
Re: Webcam OPENCV
« Reply #12 on: October 27, 2018, 12:49:30 pm »
And how to count how many pixels are brighter than some value?

Edson

  • Hero Member
  • *****
  • Posts: 1301
Re: Webcam OPENCV
« Reply #13 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.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Webcam OPENCV
« Reply #14 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, HSL and HSV (Wikipedia)
« Last Edit: October 28, 2018, 01:04:47 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018