framegrabber 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e85230c8feff750acc1216b7e0a300ec237879b0e2fa6b09e3ce0b22d38768d8
4
- data.tar.gz: 50ccf739a1d30d016a2958081bc9e856fca5d47c28d6b1d020d3c02c41eff303
3
+ metadata.gz: ca71c2ed88eb8c9fff0b84e5ccce2e2b3cd47a592003c6873211e010ff6f1030
4
+ data.tar.gz: 78452778dc8da4d4d448785d1d7c1d9cf2c03ca25115eb267f6096f73b57a329
5
5
  SHA512:
6
- metadata.gz: 2d09d0a476009f5df20eabfb458284f7908721532f64653d3031e582c6d5bb8d334f977058951b38ee27e698e876405675257b559bf1cf7847a70b6596a29189
7
- data.tar.gz: db51d1a46ce336c1368a00877106a6246037f70340e5318bd49e1522696f2e4b7c5a31d4003c7f897df5695170e6b3b8921020f9a2d64349f606d1ec18afdeea
6
+ metadata.gz: e3769f1926ff4bf6f6e74c898cdeb0475b9c2a1e42fd5670c17c2e3368cb0fafa51da76492c379321cd69667171f02733b03df9b067373758706200113050007
7
+ data.tar.gz: 4d203839ec8072ced2e3f972c714910496374fa43e33eb83e043d6221f805f41d4859f970e033b8a0cb7dd9a5102450bf0fc0ee1a4ebf02e299f555d02618e6a
data/Gemfile.lock CHANGED
@@ -30,6 +30,7 @@ GEM
30
30
 
31
31
  PLATFORMS
32
32
  arm64-darwin-21
33
+ arm64-darwin-24
33
34
 
34
35
  DEPENDENCIES
35
36
  framegrabber!
data/README.md CHANGED
@@ -42,7 +42,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
42
42
  def grab_a_nice_image
43
43
  # Open a camera, camera ids are numbered starting with 0.
44
44
  # We support only one camera at a time.
45
- # You can call this now and grab multiple frames
45
+ # You can call this once and grab multiple frames
46
46
  # before you close it.
47
47
  Framegrabber.open(0)
48
48
 
@@ -53,10 +53,9 @@ def grab_a_nice_image
53
53
  @image = Framegrabber.grab_image
54
54
 
55
55
  rescue RuntimeError => e
56
-
57
- # Camera may be unavailable or frame might be empty
58
- # At this point we don't have nice error handling
59
- puts "Oh no! #{e.message}"
56
+
57
+ # Camera may be unavailable or frame might be empty
58
+ puts "Oh no! #{e.message}"
60
59
  ensure
61
60
 
62
61
  # Camera will stay active until it is released
@@ -72,7 +71,7 @@ Use `bin/console` to poke around and see what you can improve.
72
71
 
73
72
  ## Contributing
74
73
 
75
- Bug reports and pull requests are welcome on GitHub at https://github.com/khasinski/framegrabber. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/framegrabber/blob/master/CODE_OF_CONDUCT.md).
74
+ Bug reports and pull requests are welcome on GitHub at https://github.com/khasinski/framegrabber. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/khasinski/framegrabber/blob/master/CODE_OF_CONDUCT.md).
76
75
 
77
76
  ## License
78
77
 
@@ -1,9 +1,13 @@
1
- require "mkmf"
2
- require "pkg-config"
1
+ require 'mkmf'
3
2
 
4
- $CXXFLAGS << " -std=c++11 "
3
+ $CXXFLAGS << ' -std=c++11 '
5
4
 
6
- $INCFLAGS << " " + PKGConfig.cflags("opencv4")
7
- $LDFLAGS << " " + PKGConfig.libs("opencv4")
5
+ # Direct paths for OpenCV
6
+ opencv_prefix = '/opt/homebrew/opt/opencv'
7
+ $INCFLAGS << " -I#{opencv_prefix}/include/opencv4"
8
+ $LDFLAGS << " -L#{opencv_prefix}/lib"
9
+ $LDFLAGS << ' -lopencv_gapi -lopencv_stitching -lopencv_alphamat -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs -lopencv_img_hash -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_sfm -lopencv_signal -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_highgui -lopencv_datasets -lopencv_text -lopencv_plot -lopencv_videostab -lopencv_videoio -lopencv_viz -lopencv_wechat_qrcode -lopencv_xfeatures2d -lopencv_shape -lopencv_ml -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_dnn -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core'
8
10
 
9
- create_makefile("grab_frame_ext")
11
+ have_header('unistd.h') # for usleep
12
+
13
+ create_makefile('grab_frame_ext')
@@ -2,21 +2,37 @@
2
2
  #include <opencv2/core.hpp>
3
3
  #include <opencv2/videoio.hpp>
4
4
  #include <grab_frame_ext.hpp>
5
+ #include <unistd.h>
5
6
 
6
7
  using namespace cv;
7
8
  using namespace std;
8
9
 
9
10
  static VALUE open(VALUE _self, VALUE deviceID) {
10
11
  int camID = NUM2INT(deviceID);
11
- Mat frame;
12
12
  cap.open(camID);
13
13
 
14
- cap.read(frame);
15
- sleep(1);
16
-
17
14
  if (!cap.isOpened()) {
18
15
  rb_raise(rb_eRuntimeError, "Unable to open camera %d", camID);
19
16
  }
17
+
18
+ // Wait for camera to provide a valid frame
19
+ Mat frame;
20
+ int attempts = 0;
21
+ const int max_attempts = 50; // 5 seconds at 100ms intervals
22
+ while (attempts < max_attempts) {
23
+ cap.read(frame);
24
+ if (!frame.empty()) {
25
+ break;
26
+ }
27
+ usleep(100000); // 100ms
28
+ attempts++;
29
+ }
30
+
31
+ if (frame.empty()) {
32
+ cap.release();
33
+ rb_raise(rb_eRuntimeError, "Camera %d failed to provide valid frame within timeout", camID);
34
+ }
35
+
20
36
  return Qnil;
21
37
  }
22
38
 
@@ -51,9 +67,9 @@ static VALUE grab_frame(VALUE _self) {
51
67
  for(j=0; j<frame.cols; j++) {
52
68
  VALUE pixel = rb_ary_new_capa(3);
53
69
  unsigned char * p = frame.ptr(i, j); // Y first, X after
54
- rb_ary_store(pixel, 2, ULL2NUM(p[2]*255)); // R
55
- rb_ary_store(pixel, 1, ULL2NUM(p[1]*255)); // G
56
- rb_ary_store(pixel, 0, ULL2NUM(p[0]*255)); // B
70
+ rb_ary_store(pixel, 0, ULL2NUM(p[2])); // R
71
+ rb_ary_store(pixel, 1, ULL2NUM(p[1])); // G
72
+ rb_ary_store(pixel, 2, ULL2NUM(p[0])); // B
57
73
 
58
74
  rb_ary_store(row, j, pixel);
59
75
  }
Binary file
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Framegrabber
4
- VERSION = "0.1.0"
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/framegrabber.rb CHANGED
@@ -1,18 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "framegrabber/version"
4
- require "grab_frame_ext"
3
+ require_relative 'framegrabber/version'
4
+ require 'grab_frame_ext'
5
5
  begin
6
6
  require 'rmagick'
7
7
  rescue LoadError
8
8
  end
9
9
 
10
-
11
10
  module Framegrabber
12
- if const_defined?("Magick")
11
+ if const_defined?('Magick')
13
12
  def self.grab_image
13
+ # Discard first frame (original hack to ensure camera is ready)
14
+ grab_frame
14
15
  frame = grab_frame
15
- Magick::Image.constitute(frame.first.size, frame.size, "BGR", frame.flatten)
16
+
17
+ # Use system ImageMagick to convert raw RGB data to image
18
+ require 'tempfile'
19
+ Tempfile.open(['framegrabber', '.rgb']) do |temp_rgb|
20
+ temp_rgb.binmode
21
+ temp_rgb.write(frame.flatten.pack('C*'))
22
+ temp_rgb.close
23
+
24
+ Tempfile.open(['framegrabber', '.png']) do |temp_png|
25
+ temp_png.close
26
+
27
+ # Convert RGB data to PNG using ImageMagick
28
+ system('magick', '-size', "#{frame.first.size}x#{frame.size}",
29
+ '-depth', '8', "rgb:#{temp_rgb.path}", temp_png.path)
30
+
31
+ # Read the PNG with RMagick
32
+ img = Magick::Image.read(temp_png.path).first
33
+ return img
34
+ end
35
+ end
16
36
  end
17
37
  end
18
38
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: framegrabber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Krzysztof Hasiński
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-09-30 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rake-compiler
@@ -70,6 +69,7 @@ files:
70
69
  - ext/grab_frame_ext/extconf.rb
71
70
  - ext/grab_frame_ext/grab_frame_ext.cpp
72
71
  - ext/grab_frame_ext/grab_frame_ext.hpp
72
+ - framegrabber-0.1.0.gem
73
73
  - lib/framegrabber.rb
74
74
  - lib/framegrabber/version.rb
75
75
  - sig/framegrabber.rbs
@@ -79,7 +79,6 @@ licenses:
79
79
  metadata:
80
80
  homepage_uri: https://github.com/khasinski/framegrabber
81
81
  source_code_uri: https://github.com/khasinski/framegrabber
82
- post_install_message:
83
82
  rdoc_options: []
84
83
  require_paths:
85
84
  - lib
@@ -94,8 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
93
  - !ruby/object:Gem::Version
95
94
  version: '0'
96
95
  requirements: []
97
- rubygems_version: 3.3.7
98
- signing_key:
96
+ rubygems_version: 3.6.8
99
97
  specification_version: 4
100
98
  summary: Uses OpenCV to grab frames from cameras
101
99
  test_files: []