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 +4 -4
- data/Gemfile.lock +1 -0
- data/README.md +5 -6
- data/ext/grab_frame_ext/extconf.rb +10 -6
- data/ext/grab_frame_ext/grab_frame_ext.cpp +23 -7
- data/framegrabber-0.1.0.gem +0 -0
- data/lib/framegrabber/version.rb +1 -1
- data/lib/framegrabber.rb +25 -5
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca71c2ed88eb8c9fff0b84e5ccce2e2b3cd47a592003c6873211e010ff6f1030
|
|
4
|
+
data.tar.gz: 78452778dc8da4d4d448785d1d7c1d9cf2c03ca25115eb267f6096f73b57a329
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e3769f1926ff4bf6f6e74c898cdeb0475b9c2a1e42fd5670c17c2e3368cb0fafa51da76492c379321cd69667171f02733b03df9b067373758706200113050007
|
|
7
|
+
data.tar.gz: 4d203839ec8072ced2e3f972c714910496374fa43e33eb83e043d6221f805f41d4859f970e033b8a0cb7dd9a5102450bf0fc0ee1a4ebf02e299f555d02618e6a
|
data/Gemfile.lock
CHANGED
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
|
|
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
|
-
|
|
58
|
-
|
|
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/
|
|
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
|
|
2
|
-
require "pkg-config"
|
|
1
|
+
require 'mkmf'
|
|
3
2
|
|
|
4
|
-
$CXXFLAGS <<
|
|
3
|
+
$CXXFLAGS << ' -std=c++11 '
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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,
|
|
55
|
-
rb_ary_store(pixel, 1, ULL2NUM(p[1]
|
|
56
|
-
rb_ary_store(pixel,
|
|
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
|
data/lib/framegrabber/version.rb
CHANGED
data/lib/framegrabber.rb
CHANGED
|
@@ -1,18 +1,38 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require
|
|
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?(
|
|
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
|
-
|
|
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.
|
|
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:
|
|
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.
|
|
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: []
|