70 Commits

Autor SHA1 Mensagem Data
Peter Braden e3b20082ab Merge pull request #98 from hybridgroup/master
Added coffee script examplesand updated HighGUI blockingWaitKey.
2014-02-10 18:06:59 -08:00
Ron Evans fbb030e571 Merge pull request #4 from hybridgroup/face-detection-examples
Face detection examples
2014-01-10 18:47:20 -08:00
Edgar O Silva 1c96622c67 Use recursinve frame reading (instead of time interval) from video feed to try and hit max frames per second. 2014-01-10 16:01:01 -06:00
Edgar O Silva 77a6d19c3b Reading less frames per second avoids the issue of multiple faces detected when only one exists due to the same frame being updated while image detection processing is executed. 2014-01-10 15:59:29 -06:00
Ron Evans e00f24b3e4 Merge pull request #3 from hybridgroup/face-detection
Video feed with face detection example.
2014-01-09 17:43:08 -08:00
Edgar O Silva d75f437b73 Remove commented out code. 2014-01-09 19:15:42 -06:00
Edgar O Silva a6d6be2d7d Video feed with face detection example. 2014-01-09 19:12:03 -06:00
Andrew Stewart 52e03bb7f3 Merge pull request #2 from hybridgroup/examples-waitkey-upd
Added example for video feed applying gaussianBlur and canny edges filte...
2014-01-09 08:47:13 -08:00
Edgar O Silva 9e0367e9f9 Fixed typos in camera examples. 2014-01-08 15:09:04 -06:00
Edgar O Silva 22c86364c7 Added example for video feed applying gaussianBlur and canny edges filter to the video frame feed. Updated typo in camera example. 2014-01-08 14:33:03 -06:00
Andrew Stewart 5a3cc35d25 Merge pull request #1 from hybridgroup/examples-waitkey-upd
Added coffee script examplesand updated HighGUI blockingWaitKey.
2014-01-08 10:14:00 -08:00
Edgar O Silva 73c47177e2 rename examples folder to be more in accordance with the current examples naming convention. 2014-01-08 12:11:49 -06:00
Edgar O Silva fc518a1459 Remove white space name in Coffescript examples folder. 2014-01-08 11:48:15 -06:00
Edgar O Silva db3322ebcd Fix to use always the first param as timeout if only that one was provided while keeping backwards compatability with 2 params. 2014-01-07 20:36:08 -06:00
Edgar O Silva c7ae7140ea Added coffee script examples based on opencv tutorials and updated blockWaitKey function. 2014-01-07 20:28:06 -06:00
Peter Braden 1d9072aefb Merge branch 'master' of github.com:magicode/node-opencv into magicode-master
Conflicts:
	src/Matrix.cc
	src/Matrix.h
2013-12-23 17:22:42 -08:00
Peter Braden 6f9f38112b 0.4.0 2013-12-23 16:09:45 -08:00
Peter Braden f66364f1bb Fix for mavericks / homebrew re #87
Basically just copying solution from https://github.com/mshick/node-protobuf/commit/a071e792065770c9e7372b409d37f295f9473ece

Actually have no idea _why_ this works - assume there's some intricacies with xcode on mavericks.
2013-12-23 16:08:34 -08:00
Peter Braden 0d53c15058 Merge pull request #85 from fastner/fix/tobuffer-options
Add support for options in async toBuffer()
2013-10-09 15:11:59 -07:00
Sebastian Fastner bbf36e72b1 Add parameter support to async buffer generation 2013-10-03 16:32:13 +02:00
Sebastian Fastner b79c30069f Add arguments support for async toBuffer 2013-10-03 16:01:33 +02:00
magicode fddd01a3d1 add pixel function and floodFill function 2013-09-29 21:39:56 +03:00
Peter Braden dd5961cfe2 Merge pull request #72 from eschnou/feature_contour_moments
Compute the moments of a contour
2013-09-05 05:42:58 -07:00
Peter Braden 2c5324df41 Merge pull request #71 from eschnou/fix_motion_track_example
Fixed the motion track example
2013-09-05 05:33:50 -07:00
Laurent Eschenauer 0520e6dcea Compute the moments of a contour
Added a moments method to the contour object and an example
using resulting moments to display a cross at the "center
of gravity" of a contour.
2013-08-27 22:13:22 +02:00
Laurent Eschenauer 612d0f1c21 Fixed the motion track example 2013-08-27 21:46:32 +02:00
Peter Braden 65d9e3ea99 Merge pull request #70 from SergeMv/master
Did several changes and added some new functions
2013-08-25 02:07:25 -07:00
Paul 824ffceeb2 removed unneeded stuff 2013-08-22 23:48:45 +04:00
Paul 5daf9c0f4d Merge branch 'master' of https://github.com/SergeMv/node-opencv 2013-08-22 23:45:11 +04:00
Paul 187b6d073a added some functions: cvtColor, split, merge, equalizeHist 2013-08-22 23:43:41 +04:00
Paul 146925ee6d provided interpolation option for the resize() func 2013-08-22 19:37:08 +04:00
Paul e7300b1cfc added options for toBuffer() func 2013-08-22 19:07:10 +04:00
SergeMv e0c4d42503 Merge pull request #1 from SergeMv/rotate
fixed the rotate() func for angles which are multiple of 90
2013-08-22 06:07:28 -07:00
Paul b2ed603a2a fixed the rotate() func for angles which are multiple of 90 2013-08-22 16:55:32 +04:00
Paul 3105e14f25 implemented copyTo() func 2013-08-22 05:06:58 +04:00
Peter Braden 276e42bffc Merge pull request #63 from timfpark/master
Add absDiff, bitwiseXor, and countNonZero to Matrix operations
2013-07-30 09:51:55 -07:00
Tim Park ce742ecce2 rename test to match combined tests 2013-07-29 13:21:37 -07:00
Tim Park 6bdaa3a24f combine absDiff and countNonZero tests 2013-07-29 13:17:49 -07:00
Peter Braden cceea7b498 Merge pull request #62 from SonicHedgehog/package.json
Enhance package.json
2013-07-29 13:10:03 -07:00
Tim Park d60e3d11d5 add countNonZero to Matrix operations 2013-07-29 12:54:38 -07:00
Tim Park 363b950f1e add tests for bitwiseXor and absDiff 2013-07-29 10:48:44 -07:00
Jakob Krigovsky 813e5ee55f Specify repository url in package.json 2013-07-29 03:30:05 +02:00
Jakob Krigovsky 852de17b47 Specify MIT license in package.json 2013-07-29 03:27:56 +02:00
Jakob Krigovsky a190298eaf Specify necessary node version in package.json correctly 2013-07-29 03:27:05 +02:00
Tim Park 4ce14beb96 Add bitwiseXor and absDiff to Matrix operations 2013-07-28 11:25:01 -07:00
Peter Braden b8ec62e5f8 example of roi 2013-07-26 10:41:13 -07:00
Peter Braden 03a00c062f Merge pull request #59 from penguin359/master
Smoke test now uses portable file path
2013-07-23 10:06:42 -07:00
Peter Braden d9f0b16f16 Merge pull request #60 from carthagan/patch-1
Fix of bindings.gyo for windows
2013-07-23 10:05:03 -07:00
carthagan 7ea1435491 Fix of bindings.gyo for windows
Adding includes in windows BuildMS
2013-07-19 09:20:56 -07:00
Loren M. Lang 13488fa94b Smoke test now uses portable file path
Added a sanity check to ensure smoke.sh is run from the correct folder
and use a relative path to the mona image so it works on any system.
2013-07-17 22:26:16 -07:00
Peter Braden 85e1ce2448 0.3.1 2013-07-17 15:48:12 -07:00
Peter Braden 3b4c361f5c Merge pull request #57 from magicode/master
fix issues #3
2013-07-17 15:46:07 -07:00
magicode 5eb7e836c3 fix issues #3 2013-07-17 08:00:12 +03:00
Peter Braden abb20798c3 0.3.0 2013-06-19 11:27:12 -07:00
Peter Braden 7548d39616 Merge branch 'master' of github.com:peterbraden/node-opencv
Conflicts:
	src/Matrix.cc
	src/Matrix.h
2013-06-19 11:26:56 -07:00
Peter Braden 762ac42f3b 0.2.0 2013-06-19 11:23:24 -07:00
Peter Braden 27f722e6aa Merge pull request #54 from smoodiver/master
Examples, added err argument to callback functions where missing
2013-06-09 16:22:24 -07:00
Ray Smoodiver 1e5a0f2a23 Added err arguments
Added err arguments to callback functions
2013-06-09 18:19:06 +12:00
Ray Smoodiver 4cc5eff25b Added err arguments
OpenCV functions now seem to return (err, val) style arguments. Updated example to handle
2013-06-09 18:16:03 +12:00
Peter Braden c93cfb782b Merge pull request #50 from gluxon/master
Use GitHub Flavored Markdown for JavaScript code and bash
2013-05-14 09:20:01 -07:00
Brandon Cheng bce9d95c29 use github flavored markdown for javascript and bash 2013-05-13 17:00:42 -04:00
Peter Braden 25bec10b28 Merge pull request #49 from nolith/meanStdDev
meanStdDev for Matrix
2013-05-09 10:02:43 -07:00
Alessio Caiazza f5df8f6599 meanStdDev for Matrix 2013-05-09 18:03:38 +02:00
Peter Braden f6ff1e58b5 Merge pull request #48 from mattholl/master
Just fixed a tiny issue where err wasn't passed as the first argument to read()
2013-05-07 15:16:21 -07:00
mattholl e507377a80 fixed tiny issue where err is missing as the first argument to read from a video stream 2013-05-07 19:37:07 +01:00
Peter Braden aa7b3317fe Merge pull request #46 from RNELord/master
Matrix::flip, Matrix::ROI, Matrix::rotate
2013-05-01 13:07:53 -07:00
Ryan Lord 7b3835bbf5 Matrix::rotate bind using cv::warpAffine 2013-05-01 14:12:30 +01:00
Ryan Lord c3d1379cd5 Added ROI bindings to Matrix 2013-05-01 11:50:37 +01:00
Ryan Lord c4a20bb279 Made exception from ::flip throw a type error 2013-05-01 02:18:55 +01:00
Ryan Lord cca52ad691 Added cv::flip function to Matrix objects 2013-05-01 02:10:27 +01:00
29 arquivos alterados com 27266 adições e 115 exclusões
+1
Ver Arquivo
@@ -4,4 +4,5 @@ build
node_modules
npm-debug.log
out*.jpg
out*.png
examples/*.avi
+101 -79
Ver Arquivo
@@ -13,31 +13,31 @@ You'll need OpenCV 2.3.1 installed.
Then:
npm install opencv
```bash
$ npm install opencv
```
Or to build the repo:
node-gyp rebuild
```bash
$ node-gyp rebuild
```
## Examples
### Face Detection
cv.readImage("./examples/test.jpg", function(err, im){
im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){
for (var i=0;i<faces.length; i++){
var x = faces[i]
im.ellipse(x.x + x.width/2, x.y + x.height/2, x.width/2, x.height/2);
}
im.save('./out.jpg');
});
})
```javascript
cv.readImage("./examples/test.jpg", function(err, im){
im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){
for (var i=0;i<faces.length; i++){
var x = faces[i]
im.ellipse(x.x + x.width/2, x.y + x.height/2, x.width/2, x.height/2);
}
im.save('./out.jpg');
});
})
```
## API Documentation
@@ -49,42 +49,52 @@ base datastructure in OpenCV. Things like images are just matrices of pixels.
#### Creation
new Matrix(rows, cols)
```javascript
new Matrix(rows, cols)
```
Or if you're thinking of a Matrix as an image:
new Matrix(height, width)
```javascript
new Matrix(height, width)
```
Or you can use opencv to read in image files. Supported formats are in the OpenCV docs, but jpgs etc are supported.
cv.readImage(filename, function(mat){
...
})
```javascript
cv.readImage(filename, function(mat){
...
})
cv.readImage(buffer, function(mat){
...
})
cv.readImage(buffer, function(mat){
...
})
```
If you need to pipe data into an image, you can use an ImageDataStream:
var s = new cv.ImageDataStream()
```javascript
var s = new cv.ImageDataStream()
s.on('load', function(matrix){
...
})
s.on('load', function(matrix){
...
})
fs.createReadStream('./examples/test.jpg').pipe(s);
fs.createReadStream('./examples/test.jpg').pipe(s);
```
If however, you have a series of images, and you wish to stream them into a
stream of Matrices, you can use an ImageStream. Thus:
var s = new cv.ImageStream()
```javascript
var s = new cv.ImageStream()
s.on('data', function(matrix){
...
})
s.on('data', function(matrix){
...
})
ardrone.createPngStream().pipe(s);
ardrone.createPngStream().pipe(s);
```
Note: Each 'data' event into the ImageStream should be a complete image buffer.
@@ -92,36 +102,42 @@ Note: Each 'data' event into the ImageStream should be a complete image buffer.
#### Accessing Data
var mat = new cv.Matrix.Eye(4,4); // Create identity matrix
```javascript
var mat = new cv.Matrix.Eye(4,4); // Create identity matrix
mat.get(0,0) // 1
mat.row(0) // [1,0,0,0]
mat.col(4) // [0,0,0,1]
mat.get(0,0) // 1
mat.row(0) // [1,0,0,0]
mat.col(4) // [0,0,0,1]
```
##### Save
mat.save('./pic.jpg')
```javascript
mat.save('./pic.jpg')
```
or:
var buff = mat.toBuffer()
```javascript
var buff = mat.toBuffer()
```
#### Image Processing
im.convertGrayscale()
im.canny(5, 300)
im.houghLinesP()
```javascript
im.convertGrayscale()
im.canny(5, 300)
im.houghLinesP()
```
#### Simple Drawing
im.ellipse(x, y)
im.line([x1,y1], [x2, y2])
```javascript
im.ellipse(x, y)
im.line([x1,y1], [x2, y2])
```
#### Object Detection
@@ -129,21 +145,25 @@ There is a shortcut method for
[Viola-Jones Haar Cascade](http://www.cognotics.com/opencv/servo_2007_series/part_2/sidebar.html) object
detection. This can be used for face detection etc.
mat.detectObject(haar_cascade_xml, opts, function(err, matches){})
```javascript
mat.detectObject(haar_cascade_xml, opts, function(err, matches){})
```
For convenience in face recognition, cv.FACE_CASCADE is a cascade that can be used for frontal face recognition.
Also:
mat.goodFeaturesToTrack
```javascript
mat.goodFeaturesToTrack
```
#### Contours
mat.findCountours
mat.drawContour
mat.drawAllContours
```javascript
mat.findCountours
mat.drawContour
mat.drawAllContours
```
### Using Contours
@@ -151,33 +171,35 @@ Also:
functions for accessing, computing with, and altering the contours contained in it.
See [relevant source code](src/Contours.cc) and [examples](examples/)
var contours = im.findContours;
```javascript
var contours = im.findContours;
# Count of contours in the Contours object
contours.size();
# Count of contours in the Contours object
contours.size();
# Count of corners(verticies) of contour `index`
contours.cornerCount(index);
# Count of corners(verticies) of contour `index`
contours.cornerCount(index);
# Access vertex data of contours
for(var c = 0; c < contours.size(); ++c) {
console.log("Contour " + c);
for(var i = 0; i < contours.cornerCount(c); ++i) {
var point = contours.point(c, i);
console.log("(" + point.x + "," + point.y + ")");"
}
}
# Access vertex data of contours
for(var c = 0; c < contours.size(); ++c) {
console.log("Contour " + c);
for(var i = 0; i < contours.cornerCount(c); ++i) {
var point = contours.point(c, i);
console.log("(" + point.x + "," + point.y + ")");"
}
}
# Computations of contour `index`
contours.area(index);
contours.arcLength(index, isClosed);
contours.boundingRect(index);
contours.minAreaRect(index);
contours.isConvex(index);
# Computations of contour `index`
contours.area(index);
contours.arcLength(index, isClosed);
contours.boundingRect(index);
contours.minAreaRect(index);
contours.isConvex(index);
# Destructively alter contour `index`
contours.approxPolyDP(index, epsilon, isClosed);
contours.convexHull(index, clockwise);
# Destructively alter contour `index`
contours.approxPolyDP(index, epsilon, isClosed);
contours.convexHull(index, clockwise);
```
## MIT License
The library is distributed under the MIT License - if for some reason that
+10 -1
Ver Arquivo
@@ -16,8 +16,14 @@
, 'libraries': [
'<!@(pkg-config --libs opencv)'
]
# For windows
,'include_dirs': [
'<!@(pkg-config --cflags opencv)'
]
, 'cflags': [
'<!@(pkg-config --cflags --libs "opencv >= 2.3.1" )'
'<!@(pkg-config --cflags "opencv >= 2.3.1" )'
, '-Wall'
]
, 'cflags!' : [ '-fno-exceptions']
@@ -27,6 +33,9 @@
# cflags on OS X are stupid and have to be defined like this
'xcode_settings': {
'OTHER_CFLAGS': [
"-mmacosx-version-min=10.7",
"-std=c++11",
"-stdlib=libc++",
'<!@(pkg-config --cflags opencv)'
]
, "GCC_ENABLE_CPP_RTTI": "YES"
+31
Ver Arquivo
@@ -0,0 +1,31 @@
cv = require 'opencv'
# we create a function helper to display the images.
displayImage = (windowName, img) ->
namedWindow = new cv.NamedWindow(windowName)
namedWindow.show(img)
namedWindow.blockingWaitKey(0, 5000)
# Load both sources to be blended
cv.readImage("./images/windows-logo.png", (err, src1) ->
# Display Source 1
displayImage('Source 1', src1)
# Load source #2
cv.readImage("./images/linux-logo.png", (err, src2) ->
# Display Source 2
displayImage('Source 2', src2)
# We use the addWeighted opencv wrapper to blend the images.
# we need to use a different image object, since src1 and src2
# will be manipulated.
result = new cv.Matrix(src1.width(), src2.height())
result.addWeighted(src1, 0.7, src2, 0.9)
result.save("./tmp/blended.png")
# Display Blended result 2
displayImage('Blended', result)
)
)
@@ -0,0 +1,56 @@
cv = require 'opencv'
# First we create a new VideoCapture object to get
# video from the camera (0 for default camera)
camera = new cv.VideoCapture(1)
# we create a window to display the Video frames
namedWindow = new cv.NamedWindow('Video', 0)
color = [255,0,0]
frameRead = () ->
# camera.read allows us to retrieve the current
# frame to be displayed in the video window.
camera.read((err, im) ->
# We can check for errors and even break the
# program execution if an error is detected here.
console.log "The err ==>#{ err }" if err
# There is no need to display the image width or Height
# but I leave this here in case anyone needs to check them.
#console.log("Width: #{im.width()}")
#console.log("height: #{im.height()}")
# Before working with the frame we need to check the image
# is already available and has a width and height greater than 0,
# otherwise it will fail when trying to do namedWindow.show()
# and the image has width or height equal or less than 0.
if im.width() > 0 and im.height() > 0
#console.log("Interval ID => #{ intervalId }")
#console.log(intervalId)
clearInterval(intervalId) if intervalId?
im.detectObject('./haarcascades/haarcascade_frontalface_alt.xml', {}, (err, faces) ->
for face in faces
im.rectangle([face.x, face.y], [face.x + face.width, face.y + face.height], [0,255,0], 2)
# We use the previously created namedWindow to display the
# video frame to wich we applied the blur and filter.
namedWindow.show(im)
# Finally we get the key pressed on the window to terminate
# execution of the program.
res = namedWindow.blockingWaitKey(0, 20)
# In this case we terminate the program if any key is pressed.
#if res >= 0 then do not set a new timeout to get a new frame.
setTimeout(frameRead, 5) if res < 0
)
)
# We set an interval to retrieve frames from the
# video source and we get the intervalId so we can
# stop the program by pressing any key on the video feed window.
intervalId = setInterval(() ->
frameRead(intervalId)
, 100)
@@ -0,0 +1,49 @@
cv = require 'opencv'
# First we create a new VideoCapture object to get
# video from the camera (0 for default camera)
camera = new cv.VideoCapture(1)
# we create a window to display the Video frames
namedWindow = new cv.NamedWindow('Video',1)
color = [255,0,0]
# We set an interval to retrieve frames from the
# video source and we get the intervalId so we can
# stop the program from the video feed window.
intervalId = setInterval(()->
# camera.read allows us to retrieve the current
# frame to be displayed in the video window.
camera.read((err, im) ->
# We can check for errors and even break the
# program execution if an error is detected here.
console.log "The err ==>#{ err }" if err
# There is no need to display the image width or Height
# but I leave this here in case anyone needs to check them.
#console.log("Width: #{im.width()}")
#console.log("height: #{im.height()}")
# Before working with the frame we need to check the image
# is already available and has a width and height greater than 0,
# otherwise it will fail when trying to do namedWindow.show()
# and the image has width or height equal or less than 0.
if im.width() > 0 and im.height() > 0
im.detectObject('./haarcascades/haarcascade_frontalface_alt.xml', {}, (err, faces) ->
for face in faces
im.rectangle([face.x, face.y], [face.x + face.width, face.y + face.height], [0,255,0], 2)
# We use the previously created namedWindow to display the
# video frame to wich we applied the blur and filter.
namedWindow.show(im)
)
# Finally we get the key pressed on the window to terminate
# execution of the program.
res = namedWindow.blockingWaitKey(0, 50)
# In this case I terminate the program if any key is pressed.
if res >= 0 then clearInterval(intervalId)
)
, 150)
@@ -0,0 +1,58 @@
cv = require 'opencv'
# First we create a new VideoCapture object to get
# video from the camera (0 for default camera)
camera = new cv.VideoCapture(1)
# we create a window to display the Video frames
namedWindow = new cv.NamedWindow('Video',1)
# We set an interval to retrieve frames from the
# video source and we get the intervalId so we can
# stop the program from the video feed window.
intervalId = setInterval(()->
# camera.read allows us to retrieve the current
# frame to be displayed in the video window.
camera.read((err, im) ->
# We can check for errors and even break the
# program execution if an error is detected here.
console.log "The err ==>#{ err }" if err
# There is no need to display the image width or Height
# but I leave this here in case anyone needs to check them.
#console.log("Width: #{im.width()}")
#console.log("height: #{im.height()}")
# Before working with the frame we need to check the image
# is already available and has a width and height greater than 0,
# otherwise it will fail when trying to do namedWindow.show()
# and the image has width or height equal or less than 0.
if im.width() > 0 and im.height() > 0
# We apply filters and effects to the frame we got from the
# camera to manipulate the video that we'll display.
# First we convert to grayscale.
im.convertGrayscale()
# We then apply GaussianBlur.
# It takes an array of type double and size 2
# that indicates how strong the gaussian blur should be.
im.gaussianBlur([7,7])
# We then apply canny edge filtering.
# Params are lower and higher threshold and aperture size,
# although nodejs-opencv overwrite the aperture size param
# with 0. An update to consider it is needed.
im.canny(0, 30, 3)
# We use the previously created namedWindow to display the
# video frame to wich we applied the blur and filter.
namedWindow.show(im)
# Finally we get the key pressed on the window to terminate
# execution of the program.
res = namedWindow.blockingWaitKey(0, 20)
console.log("KEYPRESSED => #{ res } ")
# In this case I terminate the program if any key is pressed.
if res >= 0 then clearInterval(intervalId)
)
, 50)
@@ -0,0 +1,57 @@
cv = require 'opencv'
# First we create a new VideoCapture object to get
# video from the camera (0 for default camera)
camera = new cv.VideoCapture(1)
# we create a window to display the Video frames
namedWindow = new cv.NamedWindow('Video',1)
# We set an interval to retrieve frames from the
# video source and we get the intervalId so we can
# stop the program from the video feed window.
intervalId = setInterval(()->
# camera.read allows us to retrieve the current
# frame to be displayed in the video window.
camera.read((err, im) ->
# We can check for errors and even break the
# program execution if an error is detected here.
console.log "The err ==>#{ err }" if err
# There is no need to display the image width or Height
# but I leave this here in case anyone needs to check them.
#console.log("Width: #{im.width()}")
#console.log("height: #{im.height()}")
# Before working with the frame we need to check the image
# is already available and has a width and height greater than 0,
# otherwise it will fail when trying to do namedWindow.show()
# and the image has width or height equal or less than 0.
if im.width() > 0 and im.height() > 0
# We apply filters and effects to the frame we got from the
# camera to manipulate the video that we'll display.
# First we convert to grayscale.
im.convertGrayscale()
# We then apply GaussianBlur.
# It takes an array of type double and size 2
# that indicates how strong the gaussian blur should be.
im.gaussianBlur([7,7])
# We then apply canny edge filtering.
# Params are lower and higher threshold and aperture size,
# although nodejs-opencv overwrite the aperture size param
# with 0. An update to consider it is needed.
im.canny(0, 30, 3)
# We use the previously created namedWindow to display the
# video frame to wich we applied the blur and filter.
namedWindow.show(im)
# Finally we get the key pressed on the window to terminate
# execution of the program.
res = namedWindow.blockingWaitKey(0, 20)
# In this case I terminate the program if any key is pressed.
if res >= 0 then clearInterval(intervalId)
)
, 50)
+41
Ver Arquivo
@@ -0,0 +1,41 @@
cv = require 'opencv'
# First we create a new VideoCapture object to get
# video from the camera (0 for default camera)
camera = new cv.VideoCapture(1)
# we create a window to display the Video frames
namedWindow = new cv.NamedWindow('Video',1)
# We set an interval to retrieve frames from the
# video source and we get the intervalId so we can
# stop the program from the video feed window.
intervalId = setInterval(()->
# camera.read allows us to retrieve the current
# frame to be displayed in the video window.
camera.read((err, im) ->
# We can check for errors and even break the
# program execution if an error is detected here.
console.log "The err ==>#{ err }" if err
# There is no need to display the image width or Height
# but I leave this here in case anyone needs to check them.
#console.log("Width: #{im.width()}")
#console.log("height: #{im.height()}")
# We use the previously created namedWindow to display the
# video feed frame, we need to check the image is already
# available and has a width and height greater than 0,
# otherwise namedWindow.show() will fail if any of those is 0.
namedWindow.show(im) if im.width() > 0 and im.height() > 0
# Finally we get the key pressed on the window to terminate
# execution of the program.
res = namedWindow.blockingWaitKey(0, 20)
console.log("KEYPRESSED => #{ res } ")
# In this case I terminate the program if any key is pressed.
if res >= 0 then clearInterval(intervalId)
)
, 500)
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
@@ -0,0 +1,29 @@
cv = require('opencv')
cv.readImage("./images/mona.png", (err, im) ->
# Create new NamedWindow object to hold the image
# NamedWindow takes two arguments String WindowName and String windowSize
namedWindow = new cv.NamedWindow('Display Window', '400x400')
# We add a couple of basic shapes to the image, just to show how
# to create basic shapes.
# im.rectangle([startX, StartY], [width, height], color(array of RGB)
im.rectangle([50, 50], [200, 200], [0, 255, 0], 2)
# im.ellipse(centerX, centerY, width, height, color(array of RGB)
im.ellipse(150, 150, 50, 50, [255, 255, 0], 2)
# We then tell the image to show the image we loaded.
namedWindow.show(im)
console.log("Image should be displayed inside a window.")
# Finally we tell the NamedWindow to wait for any key being pressed to close
# itself (by passing a 0 as the first param, or wait a defined amount of time
# by passing the time as a second argument (in milliseconds)
#
# If we do not tell the window to wait it will just load and show the image
# and close so fast that it will appear nothing happened.
namedWindow.blockingWaitKey(0, 5000)
console.log("And the window should close automatically or by pressing any key on it.")
)
@@ -0,0 +1,22 @@
cv = require('opencv')
cv.readImage("./images/mona.png", (err, im) ->
# Create new NamedWindow object to hold the image
# NamedWindow takes two arguments String WindowName and String windowSize
namedWindow = new cv.NamedWindow('Display Window', '400x400')
# We then tell the image to show the image we loaded.
namedWindow.show(im)
console.log("Image should be displayed inside a window.")
# Finally we tell the NamedWindow to wait for any key being pressed to close
# itself (by passing a 0 as the first param, or wait a defined amount of time
# by passing the time as a second argument (in milliseconds)
#
# If we do not tell the window to wait it will just load and show the image
# and close so fast that it will appear nothing happened.
namedWindow.blockingWaitKey(0, 5000)
console.log("And the window should close automatically or by pressing any key on it.")
)
@@ -0,0 +1,28 @@
cv = require('opencv')
cv.readImage("./images/windows-logo.png", (err, im) ->
# The nodejs-opencv has some shortcodes for image manipulation.
# We modify the image using the handy function im.convertGrayscale()
# This will overwrite the current image with a grayscaled version.
im.convertGrayscale()
# Create new NamedWindow object to hold the image
# NamedWindow takes two arguments String WindowName and String windowSize
namedWindow = new cv.NamedWindow('Display Window', '400x400')
# We then tell the image to show the image we loaded.
namedWindow.show(im)
console.log("Image should be displayed inside a window.")
# Finally we tell the NamedWindow to wait for any key being pressed to close
# itself (by passing a 0 as the first param, or wait a defined amount of time
# by passing the time as a second argument (in milliseconds)
#
# If we do not tell the window to wait it will just load and show the image
# and close so fast that it will appear nothing happened.
namedWindow.blockingWaitKey(0, 5000)
console.log("And the window should close automatically or by pressing any key on it.")
)
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 17 KiB

BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 518 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 50 KiB

+6 -1
Ver Arquivo
@@ -7,7 +7,7 @@ var maxArea = 2500;
var GREEN = [0, 255, 0]; //B, G, R
var WHITE = [255, 255, 255]; //B, G, R
var RED = [0, 0, 255]; //B, G, R
cv.readImage('./stuff.png', function(err, im) {
@@ -24,7 +24,12 @@ cv.readImage('./stuff.png', function(err, im) {
for(i = 0; i < contours.size(); i++) {
if(contours.area(i) > maxArea) {
var moments = contours.moments(i);
var cgx = Math.round(moments.m10/moments.m00);
var cgy = Math.round(moments.m01/moments.m00);
big.drawContour(contours, i, GREEN);
big.line([cgx - 5, cgy], [cgx + 5, cgy], RED);
big.line([cgx, cgy - 5], [cgx, cgy + 5], RED);
}
}
+6 -5
Ver Arquivo
@@ -1,13 +1,14 @@
var cv = require('../lib/opencv')
var path = require('path'),
cv = require('../lib/opencv');
// When opening a file, the full path must be passed to opencv
var vid = new cv.VideoCapture(path.join(__dirname, "motion.mov"));
var vid = new cv.VideoCapture("/Users/peterbraden/Desktop/repos/node-opencv/examples/motion.avi")
vid.read(function(mat){
vid.read(function(err, mat){
var track = new cv.TrackedObject(mat, [420, 110, 490, 170], {channel: "value"});
var x = 0;
var iter = function(){
vid.read(function(m2){
vid.read(function(err, m2){
x++;
var rec = track.track(m2)
console.log(">>", x, ":" , rec)
+6 -4
Ver Arquivo
@@ -4,8 +4,9 @@ var vid = new cv.VideoCapture(0)
var snap = function(){
vid.read(function(im){
vid.read(function(err, im){
im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){
if (!faces){
console.log("No Faces")
return;
@@ -13,14 +14,15 @@ var snap = function(){
var face = faces[0]
, ims = im.size()
var im2 = im.roi(face.x, face.y, face.width, face.height)
/*
im.adjustROI(
-face.y
, (face.y + face.height) - ims[0]
, -face.x
, (face.x + face.width) - ims[1])
console.log("!!", im.locateROI());
var im2 = im.clone()
*/
im2.save('out.jpg')
})
+5 -5
Ver Arquivo
@@ -50,14 +50,14 @@ util.inherits(cv.ImageDataStream, Stream);
var imagedatastream = cv.ImageDataStream.prototype;
imagedatastream.write = function(buf){
this.data.push(buf)
this.data.push(buf)
return true;
}
imagedatastream.end = function(b){
var self = this;
if (b)
imagestream.write.call(this,b);
@@ -98,7 +98,7 @@ var ods = cv.ObjectDetectionStream.prototype;
ods.write = function(m){
var self = this;
this.classifier.detectMultiScale(m,
this.classifier.detectMultiScale(m,
function(e, objs){
if (e) { throw e }
self.emit('data', objs, m);
@@ -111,7 +111,7 @@ ods.write = function(m){
cv.VideoStream = function(src){
if (src instanceof cv.VideoCapture){
this.video = src
} else {
} else {
this.video = new cv.VideoCapture(src);
}
this.readable = true;
@@ -128,7 +128,7 @@ videostream.read = function(){
var self = this;
var frame = function(){
self.video.read(function(mat){
self.video.read(function(err, mat){
self.emit('data', mat)
if (!self.paused){
process.nextTick(frame)
+16 -4
Ver Arquivo
@@ -5,15 +5,27 @@
"dependencies": {
"buffers": "0.1.1"
},
"version": "0.1.0",
"version": "0.4.0",
"devDependencies": {
"vows": "*"
},
"engine": "node >= 0.4.1",
"engines": {
"node": ">=0.4.1"
},
"license": "MIT",
"scripts": {
"preinstall": "node-gyp clean rebuild",
"test": "vows test/unit.js"
},
"keywords" : ["opencv", "computer", "vision", "quadrocopter"],
"main": "./lib/opencv"
"keywords": [
"opencv",
"computer",
"vision",
"quadrocopter"
],
"main": "./lib/opencv",
"repository": {
"type": "git",
"url": "https://github.com/peterbraden/node-opencv.git"
}
}
+6
Ver Arquivo
@@ -1,4 +1,10 @@
#!/bin/bash
if [ ! -f smoke/smoketest.js ]; then
echo "Please run smoke test from the top-level folder of the repository." >&2
exit 1
fi
node-gyp build && echo '-- Compiled OK --
' && node smoke/smoketest.js && echo '-- Smoke Done, running tests --
+1 -1
Ver Arquivo
@@ -20,7 +20,7 @@ cv.readImage("/Users/peterbraden/Downloads/orl_faces/s6/10.pgm", function(e, im)
*/
cv.readImage("/Users/peterbraden/Desktop/repos/node-opencv/examples/mona.png", function(e, mat){
cv.readImage("examples/mona.png", function(e, mat){
var th = mat.threshold(200, 200, "Threshold to Zero Inverted");
th.save('out.png')
+22
Ver Arquivo
@@ -33,6 +33,7 @@ Contour::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "boundingRect", BoundingRect);
NODE_SET_PROTOTYPE_METHOD(constructor, "minAreaRect", BoundingRect);
NODE_SET_PROTOTYPE_METHOD(constructor, "isConvex", IsConvex);
NODE_SET_PROTOTYPE_METHOD(constructor, "moments", Moments);
target->Set(String::NewSymbol("Contours"), m->GetFunction());
};
@@ -220,3 +221,24 @@ Contour::IsConvex(const Arguments &args) {
return scope.Close(Boolean::New(isContourConvex(cv::Mat(self->contours[pos]))));
}
Handle<Value>
Contour::Moments(const Arguments &args) {
HandleScope scope;
Contour *self = ObjectWrap::Unwrap<Contour>(args.This());
int pos = args[0]->NumberValue();
/// Get the moments
cv::Moments mu = moments( self->contours[pos], false );
Local<Object> res = Object::New();
res->Set(String::NewSymbol("m00"), Number::New(mu.m00));
res->Set(String::NewSymbol("m10"), Number::New(mu.m10));
res->Set(String::NewSymbol("m01"), Number::New(mu.m01));
res->Set(String::NewSymbol("m11"), Number::New(mu.m11));
return scope.Close(res);
}
+1
Ver Arquivo
@@ -24,5 +24,6 @@ class Contour: public node::ObjectWrap {
static Handle<Value> BoundingRect(const v8::Arguments&);
static Handle<Value> MinAreaRect(const v8::Arguments&);
static Handle<Value> IsConvex(const v8::Arguments&);
static Handle<Value> Moments(const v8::Arguments&);
};
+8 -1
Ver Arquivo
@@ -73,9 +73,16 @@ NamedWindow::BlockingWaitKey(const v8::Arguments& args){
HandleScope scope;
//SETUP_FUNCTION(NamedWindow)
int time = 0;
if (args.Length() > 0){
if (args.Length() > 1){
time = args[1]->IntegerValue();
}else{
if (args.Length() > 0){
time = args[0]->IntegerValue();
}
}
int res = cv::waitKey(time);
return scope.Close(Number::New(res));
}
+501 -11
Ver Arquivo
@@ -5,6 +5,8 @@
v8::Persistent<FunctionTemplate> Matrix::constructor;
cv::Scalar setColor(Local<Object> objColor);
cv::Point setPoint(Local<Object> objPoint);
cv::Rect* setRect(Local<Object> objRect);
//
@@ -34,6 +36,7 @@ Matrix::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "empty", Empty);
NODE_SET_PROTOTYPE_METHOD(constructor, "get", Get);
NODE_SET_PROTOTYPE_METHOD(constructor, "set", Set);
NODE_SET_PROTOTYPE_METHOD(constructor, "pixel", Pixel);
NODE_SET_PROTOTYPE_METHOD(constructor, "width", Width);
NODE_SET_PROTOTYPE_METHOD(constructor, "height", Height);
NODE_SET_PROTOTYPE_METHOD(constructor, "size", Size);
@@ -46,6 +49,8 @@ Matrix::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save);
NODE_SET_PROTOTYPE_METHOD(constructor, "saveAsync", SaveAsync);
NODE_SET_PROTOTYPE_METHOD(constructor, "resize", Resize);
NODE_SET_PROTOTYPE_METHOD(constructor, "rotate", Rotate);
NODE_SET_PROTOTYPE_METHOD(constructor, "copyTo", CopyTo);
NODE_SET_PROTOTYPE_METHOD(constructor, "pyrDown", PyrDown);
NODE_SET_PROTOTYPE_METHOD(constructor, "pyrUp", PyrUp);
NODE_SET_PROTOTYPE_METHOD(constructor, "channels", Channels);
@@ -54,9 +59,14 @@ Matrix::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "convertHSVscale", ConvertHSVscale);
NODE_SET_PROTOTYPE_METHOD(constructor, "gaussianBlur", GaussianBlur);
NODE_SET_PROTOTYPE_METHOD(constructor, "copy", Copy);
NODE_SET_PROTOTYPE_METHOD(constructor, "flip", Flip);
NODE_SET_PROTOTYPE_METHOD(constructor, "roi", ROI);
NODE_SET_PROTOTYPE_METHOD(constructor, "ptr", Ptr);
NODE_SET_PROTOTYPE_METHOD(constructor, "absDiff", AbsDiff);
NODE_SET_PROTOTYPE_METHOD(constructor, "addWeighted", AddWeighted);
NODE_SET_PROTOTYPE_METHOD(constructor, "split", Split);
NODE_SET_PROTOTYPE_METHOD(constructor, "bitwiseXor", BitwiseXor);
NODE_SET_PROTOTYPE_METHOD(constructor, "countNonZero", CountNonZero);
//NODE_SET_PROTOTYPE_METHOD(constructor, "split", Split);
NODE_SET_PROTOTYPE_METHOD(constructor, "canny", Canny);
NODE_SET_PROTOTYPE_METHOD(constructor, "dilate", Dilate);
NODE_SET_PROTOTYPE_METHOD(constructor, "erode", Erode);
@@ -73,6 +83,14 @@ Matrix::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "locateROI", LocateROI);
NODE_SET_PROTOTYPE_METHOD(constructor, "threshold", Threshold);
NODE_SET_PROTOTYPE_METHOD(constructor, "meanStdDev", MeanStdDev);
NODE_SET_PROTOTYPE_METHOD(constructor, "cvtColor", CvtColor);
NODE_SET_PROTOTYPE_METHOD(constructor, "split", Split);
NODE_SET_PROTOTYPE_METHOD(constructor, "merge", Merge);
NODE_SET_PROTOTYPE_METHOD(constructor, "equalizeHist", EqualizeHist);
NODE_SET_PROTOTYPE_METHOD(constructor, "floodFill", FloodFill);
NODE_SET_METHOD(constructor, "Eye", Eye);
@@ -121,6 +139,7 @@ Matrix::Matrix(cv::Mat m, cv::Rect roi): ObjectWrap() {
mat = cv::Mat(m, roi);
}
Handle<Value>
Matrix::Empty(const Arguments& args){
SETUP_FUNCTION(Matrix)
@@ -158,6 +177,43 @@ Matrix::DblGet(cv::Mat mat, int i, int j){
return val;
}
Handle<Value>
Matrix::Pixel(const Arguments& args){
SETUP_FUNCTION(Matrix)
int y = args[0]->IntegerValue();
int x = args[1]->IntegerValue();
//cv::Scalar scal = self->mat.at<uchar>(y, x);
if(args.Length() == 3){
Local<Object> objColor = args[2]->ToObject();
self->mat.at<cv::Vec3b>(y, x)[0] = (uchar) objColor->Get(0)->IntegerValue();
self->mat.at<cv::Vec3b>(y, x)[1] = (uchar) objColor->Get(1)->IntegerValue();
self->mat.at<cv::Vec3b>(y, x)[2] = (uchar) objColor->Get(2)->IntegerValue();
return scope.Close(args[2]->ToObject());
}else{
cv::Vec3b intensity = self->mat.at<cv::Vec3b>(y, x);
v8::Local<v8::Array> arr = v8::Array::New(3);
arr->Set(0, Number::New( intensity[0] ));
arr->Set(1, Number::New( intensity[1] ));
arr->Set(2, Number::New( intensity[2] ));
return scope.Close(arr);
}
return scope.Close(Undefined());
//double val = Matrix::DblGet(t, i, j);
//return scope.Close(Number::New(val));
}
Handle<Value>
Matrix::Get(const Arguments& args){
SETUP_FUNCTION(Matrix)
@@ -218,6 +274,7 @@ Matrix::Size(const Arguments& args){
return scope.Close(arr);
}
Handle<Value>
Matrix::Clone(const Arguments& args){
SETUP_FUNCTION(Matrix)
@@ -326,14 +383,47 @@ Handle<Value>
Matrix::ToBuffer(const v8::Arguments& args){
SETUP_FUNCTION(Matrix)
if (args.Length() > 0){
return Matrix::ToBufferAsync(args);
}
if ((args.Length() > 0) && (args[0]->IsFunction())) {
return Matrix::ToBufferAsync(args);
}
// SergeMv changes
// img.toBuffer({ext: ".png", pngCompression: 9}); // default png compression is 3
// img.toBuffer({ext: ".jpg", jpegQuality: 80});
// img.toBuffer(); // creates Jpeg with quality of 95 (Opencv default quality)
// via the ext you can do other image formats too (like tiff), see
// http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#imencode
//---------------------------
// Provide default value
const char *ext = ".jpg";
std::vector<int> params;
// See if the options argument is passed
if ((args.Length() > 0) && (args[0]->IsObject())) {
// Get this options argument
v8::Handle<v8::Object> options = v8::Handle<v8::Object>::Cast(args[0]);
// If the extension (image format) is provided
if (options->Has(v8::String::New("ext"))) {
v8::String::Utf8Value str ( options->Get(v8::String::New("ext"))->ToString() );
std::string str2 = std::string(*str);
ext = (const char *) str2.c_str();
}
if (options->Has(v8::String::New("jpegQuality"))) {
int compression = options->Get(v8::String::New("jpegQuality"))->IntegerValue();
params.push_back(CV_IMWRITE_JPEG_QUALITY);
params.push_back(compression);
}
if (options->Has(v8::String::New("pngCompression"))) {
int compression = options->Get(v8::String::New("pngCompression"))->IntegerValue();
params.push_back(CV_IMWRITE_PNG_COMPRESSION);
params.push_back(compression);
}
}
//---------------------------
std::vector<uchar> vec(0);
std::vector<int> params(0);//CV_IMWRITE_JPEG_QUALITY 90
cv::imencode(".jpg", self->mat, vec, params);
// We use operator * before the "ext" variable, because it converts v8::String::AsciiValue to char *
cv::imencode(ext, self->mat, vec, params);
node::Buffer *buf = node::Buffer::New(vec.size());
uchar* data = (uchar*) Buffer::Data(buf);
@@ -353,6 +443,8 @@ struct matrixToBuffer_baton_t {
Matrix *mm;
Persistent<Function> cb;
std::vector<uchar> res;
std::vector<int> params;
std::string ext;
uv_work_t request;
};
@@ -365,7 +457,34 @@ Matrix::ToBufferAsync(const v8::Arguments& args){
REQ_FUN_ARG(0, cb);
matrixToBuffer_baton_t *baton = new matrixToBuffer_baton_t();
std::string ext = std::string(".jpg");
// See if the options argument is passed
if ((args.Length() > 1) && (args[1]->IsObject())) {
// Get this options argument
v8::Handle<v8::Object> options = v8::Handle<v8::Object>::Cast(args[1]);
// If the extension (image format) is provided
if (options->Has(v8::String::New("ext"))) {
v8::String::Utf8Value str ( options->Get(v8::String::New("ext"))->ToString() );
std::string str2 = std::string(*str);
ext = str2;
}
if (options->Has(v8::String::New("jpegQuality"))) {
int compression = options->Get(v8::String::New("jpegQuality"))->IntegerValue();
baton->params.push_back(CV_IMWRITE_JPEG_QUALITY);
baton->params.push_back(compression);
}
if (options->Has(v8::String::New("pngCompression"))) {
int compression = options->Get(v8::String::New("pngCompression"))->IntegerValue();
baton->params.push_back(CV_IMWRITE_PNG_COMPRESSION);
baton->params.push_back(compression);
}
}
baton->ext = ext;
baton->mm = self;
baton->cb = Persistent<Function>::New(cb);
baton->request.data = baton;
@@ -379,9 +498,10 @@ void AsyncToBufferAsync(uv_work_t *req) {
matrixToBuffer_baton_t *baton = static_cast<matrixToBuffer_baton_t *>(req->data);
std::vector<uchar> vec(0);
std::vector<int> params(0);//CV_IMWRITE_JPEG_QUALITY 90
//std::vector<int> params(0);//CV_IMWRITE_JPEG_QUALITY 90
cv::imencode(".jpg", baton->mm->mat, vec, params);
const char * ext = (const char *) baton->ext.c_str();
cv::imencode(ext, baton->mm->mat, vec, baton->params);
baton->res = vec;
@@ -696,6 +816,54 @@ Matrix::Copy(const v8::Arguments& args) {
}
Handle<Value>
Matrix::Flip(const v8::Arguments& args) {
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
if ( args.Length() < 1 || !args[0]->IsInt32() ) {
return v8::ThrowException(Exception::TypeError(String::New(
"Flip requires an integer flipCode argument (0 = X axis, positive = Y axis, negative = both axis)")));
}
int flipCode = args[0]->ToInt32()->Value();
Local<Object> img_to_return = Matrix::constructor->GetFunction()->NewInstance();
Matrix *img = ObjectWrap::Unwrap<Matrix>(img_to_return);
cv::flip(self->mat, img->mat, flipCode);
return scope.Close(img_to_return);
}
Handle<Value>
Matrix::ROI(const v8::Arguments& args) {
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
if ( args.Length() != 4 ) {
return v8::ThrowException(Exception::TypeError(String::New(
"ROI requires x,y,w,h arguments")));
}
// although it's an image to return, it is in fact a pointer to ROI of parent matrix
Local<Object> img_to_return = Matrix::constructor->GetFunction()->NewInstance();
Matrix *img = ObjectWrap::Unwrap<Matrix>(img_to_return);
int x = args[0]->IntegerValue();
int y = args[1]->IntegerValue();
int w = args[2]->IntegerValue();
int h = args[3]->IntegerValue();
cv::Mat roi(self->mat, cv::Rect(x,y,w,h));
img->mat = roi;
return scope.Close(img_to_return);
}
Handle<Value>
Matrix::Ptr(const v8::Arguments& args) {
HandleScope scope;
@@ -715,6 +883,20 @@ Matrix::Ptr(const v8::Arguments& args) {
// return Undefined();
}
Handle<Value>
Matrix::AbsDiff(const v8::Arguments& args) {
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
Matrix *src1 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
Matrix *src2 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject());
cv::absdiff(src1->mat, src2->mat, self->mat);
return scope.Close(v8::Null());
}
Handle<Value>
Matrix::AddWeighted(const v8::Arguments& args) {
HandleScope scope;
@@ -734,15 +916,38 @@ Matrix::AddWeighted(const v8::Arguments& args) {
return scope.Close(v8::Null());
}
Handle<Value>
Matrix::BitwiseXor(const v8::Arguments& args) {
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
Matrix *src1 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
Matrix *src2 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject());
cv::bitwise_xor(src1->mat, src2->mat, self->mat);
return scope.Close(v8::Null());
}
Handle<Value>
Matrix::CountNonZero(const v8::Arguments& args) {
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
double count = (double)cv::countNonZero(self->mat);
return scope.Close(v8::Number::New(count));
}
/*Handle<Value>
Matrix::Split(const v8::Arguments& args) {
HandleScope scope;
//Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
return scope.Close(v8::Null());
}
}*/
Handle<Value>
@@ -907,6 +1112,30 @@ cv::Scalar setColor(Local<Object> objColor) {
cv::Scalar color = cv::Scalar(valB->IntegerValue(), valG->IntegerValue(), valR->IntegerValue());
return color;
}
cv::Point setPoint(Local<Object> objPoint) {
return cv::Point( objPoint->Get(0)->IntegerValue(), objPoint->Get(1)->IntegerValue() );
}
cv::Rect* setRect(Local<Object> objRect) {
if(!objRect->IsArray() || !objRect->Get(0)->IsArray() || !objRect->Get(0)->IsArray() ){
printf("error");
return 0;
};
Local<Object> point = objRect->Get(0)->ToObject();
Local<Object> size = objRect->Get(1)->ToObject();
cv::Rect ret;
ret.x = point->Get(0)->IntegerValue();
ret.y = point->Get(1)->IntegerValue();
ret.width = size->Get(0)->IntegerValue();
ret.height = size->Get(1)->IntegerValue();
return (cv::Rect*) &ret;
}
@@ -916,10 +1145,18 @@ Matrix::Resize(const v8::Arguments& args){
int x = args[0]->Uint32Value();
int y = args[1]->Uint32Value();
/*
CV_INTER_NN =0,
CV_INTER_LINEAR =1,
CV_INTER_CUBIC =2,
CV_INTER_AREA =3,
CV_INTER_LANCZOS4 =4
*/
int interpolation = (args.Length() < 3) ? (int)cv::INTER_LINEAR : args[2]->Uint32Value();
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
cv::Mat res = cv::Mat(x, y, CV_32FC3);
cv::resize(self->mat, res, cv::Size(x, y), 0, 0, cv::INTER_LINEAR);
cv::resize(self->mat, res, cv::Size(x, y), 0, 0, interpolation);
~self->mat;
self->mat = res;
@@ -927,6 +1164,58 @@ Matrix::Resize(const v8::Arguments& args){
return scope.Close(Undefined());
}
Handle<Value>
Matrix::Rotate(const v8::Arguments& args){
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
cv::Mat rotMatrix(2, 3, CV_32FC1);
cv::Mat res;
float angle = args[0]->ToNumber()->Value();
// Modification by SergeMv
//-------------
// If you provide only the angle argument and the angle is multiple of 90, then
// we do a fast thing
bool rightOrStraight = (ceil(angle) == angle) && (!((int)angle % 90))
&& (args.Length() == 1);
if (rightOrStraight) {
int angle2 = ((int)angle) % 360;
if (!angle2) { return scope.Close(Undefined()); }
if (angle2 < 0) { angle2 += 360; }
// See if we do right angle rotation, we transpose the matrix:
if (angle2 % 180) {
cv::transpose(self->mat, res);
~self->mat;
self->mat = res;
}
// Now flip the image
int mode = -1; // flip around both axes
// If counterclockwise, flip around the x-axis
if (angle2 == 90) { mode = 0; }
// If clockwise, flip around the y-axis
if (angle2 == 270) { mode = 1; }
cv::flip(self->mat, self->mat, mode);
return scope.Close(Undefined());
}
//-------------
int x = args[1]->IsUndefined() ? round(self->mat.size().width / 2) : args[1]->Uint32Value();
int y = args[1]->IsUndefined() ? round(self->mat.size().height / 2) : args[2]->Uint32Value();
cv::Point center = cv::Point(x,y);
rotMatrix = getRotationMatrix2D(center, angle, 1.0);
cv::warpAffine(self->mat, res, rotMatrix, self->mat.size());
~self->mat;
self->mat = res;
return scope.Close(Undefined());
}
Handle<Value>
Matrix::PyrDown(const v8::Arguments& args){
SETUP_FUNCTION(Matrix)
@@ -1040,3 +1329,204 @@ Matrix::Threshold(const v8::Arguments& args) {
return scope.Close(img_to_return);
}
Handle<Value>
Matrix::MeanStdDev(const v8::Arguments& args) {
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
Local<Object> mean = Matrix::constructor->GetFunction()->NewInstance();
Matrix *m_mean = ObjectWrap::Unwrap<Matrix>(mean);
Local<Object> stddev = Matrix::constructor->GetFunction()->NewInstance();
Matrix *m_stddev = ObjectWrap::Unwrap<Matrix>(stddev);
cv::meanStdDev(self->mat, m_mean->mat, m_stddev->mat);
Local<Object> data = Object::New();
data->Set(String::NewSymbol("mean"), mean);
data->Set(String::NewSymbol("stddev"), stddev);
return scope.Close(data);
}
// @author SergeMv
// Copies our (small) image into a ROI of another (big) image
// @param Object another image (destination)
// @param Number Destination x (where our image is to be copied)
// @param Number Destination y (where our image is to be copied)
// Example: smallImg.copyTo(bigImg, 50, 50);
// Note, x,y and width and height of our image must be so that
// our.width + x <= destination.width (and the same for y and height)
// both x and y must be >= 0
Handle<Value>
Matrix::CopyTo(const v8::Arguments& args) {
HandleScope scope;
Matrix * self = ObjectWrap::Unwrap<Matrix>(args.This());
int width = self->mat.size().width;
int height = self->mat.size().height;
// param 0 - destination image:
Matrix *dest = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
// param 1 - x coord of the destination
int x = args[1]->IntegerValue();
// param 2 - y coord of the destination
int y = args[2]->IntegerValue();
cv::Mat dstROI = cv::Mat(dest->mat, cv::Rect(x, y, width, height));
self->mat.copyTo(dstROI);
return scope.Close(Undefined());
}
// @author SergeMv
// Does in-place color transformation
// img.cvtColor('CV_BGR2YCrCb');
Handle<Value>
Matrix::CvtColor(const v8::Arguments& args) {
HandleScope scope;
Matrix * self = ObjectWrap::Unwrap<Matrix>(args.This());
v8::String::Utf8Value str (args[0]->ToString());
std::string str2 = std::string(*str);
const char * sTransform = (const char *) str2.c_str();
int iTransform;
//
if (!strcmp(sTransform, "CV_BGR2GRAY")) { iTransform = CV_BGR2GRAY; }
else if (!strcmp(sTransform, "CV_GRAY2BGR")) { iTransform = CV_GRAY2BGR; }
//
else if (!strcmp(sTransform, "CV_BGR2XYZ")) { iTransform = CV_BGR2XYZ; }
else if (!strcmp(sTransform, "CV_XYZ2BGR")) { iTransform = CV_XYZ2BGR; }
//
else if (!strcmp(sTransform, "CV_BGR2YCrCb")) { iTransform = CV_BGR2YCrCb; }
else if (!strcmp(sTransform, "CV_YCrCb2BGR")) { iTransform = CV_YCrCb2BGR; }
//
else if (!strcmp(sTransform, "CV_BGR2HSV")) { iTransform = CV_BGR2HSV; }
else if (!strcmp(sTransform, "CV_HSV2BGR")) { iTransform = CV_HSV2BGR; }
//
else if (!strcmp(sTransform, "CV_BGR2HLS")) { iTransform = CV_BGR2HLS; }
else if (!strcmp(sTransform, "CV_HLS2BGR")) { iTransform = CV_HLS2BGR; }
//
else if (!strcmp(sTransform, "CV_BGR2Lab")) { iTransform = CV_BGR2Lab; }
else if (!strcmp(sTransform, "CV_Lab2BGR")) { iTransform = CV_Lab2BGR; }
//
else if (!strcmp(sTransform, "CV_BGR2Luv")) { iTransform = CV_BGR2Luv; }
else if (!strcmp(sTransform, "CV_Luv2BGR")) { iTransform = CV_Luv2BGR; }
//
else if (!strcmp(sTransform, "CV_BayerBG2BGR")) { iTransform = CV_BayerBG2BGR; }
else if (!strcmp(sTransform, "CV_BayerGB2BGR")) { iTransform = CV_BayerGB2BGR; }
else if (!strcmp(sTransform, "CV_BayerRG2BGR")) { iTransform = CV_BayerRG2BGR; }
else if (!strcmp(sTransform, "CV_BayerGR2BGR")) { iTransform = CV_BayerGR2BGR; }
else {
iTransform = 0; // to avoid compiler warning
return v8::ThrowException(Exception::TypeError(String::New(
"Conversion code is unsupported")));
}
cv::cvtColor(self->mat, self->mat, iTransform);
return scope.Close(Undefined());
}
// @author SergeMv
// arrChannels = img.split();
Handle<Value>
Matrix::Split(const v8::Arguments& args) {
HandleScope scope;
Matrix * self = ObjectWrap::Unwrap<Matrix>(args.This());
vector<cv::Mat> channels;
cv::split(self->mat, channels);
unsigned int size = channels.size();
v8::Local<v8::Array> arrChannels = v8::Array::New(size);
for (unsigned int i = 0; i < size; i++) {
Local<Object> matObject = Matrix::constructor->GetFunction()->NewInstance();
Matrix * m = ObjectWrap::Unwrap<Matrix>(matObject);
m->mat = channels[i];
arrChannels->Set(i, matObject);
}
return scope.Close(arrChannels);
}
// @author SergeMv
// img.merge(arrChannels);
Handle<Value>
Matrix::Merge(const v8::Arguments& args) {
HandleScope scope;
Matrix * self = ObjectWrap::Unwrap<Matrix>(args.This());
if (!args[0]->IsArray()) {
return v8::ThrowException(Exception::TypeError(String::New(
"The argument must be an array")));
}
v8::Handle<v8::Array> jsChannels = v8::Handle<v8::Array>::Cast(args[0]);
unsigned int L = jsChannels->Length();
vector<cv::Mat> vChannels(L);
for (unsigned int i = 0; i < L; i++) {
Matrix * matObject = ObjectWrap::Unwrap<Matrix>(jsChannels->Get(i)->ToObject());
vChannels[i] = matObject->mat;
}
cv::merge(vChannels, self->mat);
return scope.Close(Undefined());
}
// @author SergeMv
// Equalizes histogram
// img.equalizeHist()
Handle<Value>
Matrix::EqualizeHist(const v8::Arguments& args) {
HandleScope scope;
Matrix * self = ObjectWrap::Unwrap<Matrix>(args.This());
cv::equalizeHist(self->mat, self->mat);
return scope.Close(Undefined());
}
Handle<Value>
Matrix::FloodFill(const Arguments& args){
SETUP_FUNCTION(Matrix)
//obj->Get(v8::String::NewSymbol("x"))
//int cv::floodFill(cv::InputOutputArray, cv::Point, cv::Scalar, cv::Rect*, cv::Scalar, cv::Scalar, int)
/* mat.floodFill( { seedPoint: [1,1] ,
newColor: [255,0,0] ,
rect:[[0,2],[30,40]] ,
loDiff : [8,90,60],
upDiff:[10,100,70]
} );*/
if(args.Length() < 1 || !args[0]->IsObject()) {
//error
}
Local<Object> obj = args[0]->ToObject();
int ret = cv::floodFill(self->mat, setPoint(obj->Get(v8::String::NewSymbol("seedPoint"))->ToObject())
, setColor(obj->Get(v8::String::NewSymbol("newColor"))->ToObject())
, obj->Get(v8::String::NewSymbol("rect"))->IsUndefined() ? 0 : setRect(obj->Get(v8::String::NewSymbol("rect"))->ToObject())
, setColor(obj->Get(v8::String::NewSymbol("loDiff"))->ToObject())
, setColor(obj->Get(v8::String::NewSymbol("upDiff"))->ToObject())
, 4 );
return scope.Close(Number::New( ret ));
}
+16 -2
Ver Arquivo
@@ -29,7 +29,6 @@ class Matrix: public node::ObjectWrap {
JSFUNC(Height)
JSFUNC(Channels)
JSFUNC(Clone)
JSFUNC(Ellipse)
JSFUNC(Rectangle)
JSFUNC(Line)
@@ -42,6 +41,7 @@ class Matrix: public node::ObjectWrap {
JSFUNC(ToBufferAsync)
JSFUNC(Resize)
JSFUNC(Rotate)
JSFUNC(PyrDown)
JSFUNC(PyrUp)
@@ -49,9 +49,14 @@ class Matrix: public node::ObjectWrap {
JSFUNC(ConvertHSVscale)
JSFUNC(GaussianBlur)
JSFUNC(Copy)
JSFUNC(Flip)
JSFUNC(ROI)
JSFUNC(Ptr)
JSFUNC(AbsDiff)
JSFUNC(AddWeighted)
JSFUNC(Split)
JSFUNC(BitwiseXor)
JSFUNC(CountNonZero)
//JSFUNC(Split)
JSFUNC(Canny)
JSFUNC(Dilate)
JSFUNC(Erode)
@@ -70,6 +75,15 @@ class Matrix: public node::ObjectWrap {
JSFUNC(AdjustROI)
JSFUNC(Threshold)
JSFUNC(MeanStdDev)
JSFUNC(CopyTo)
JSFUNC(CvtColor)
JSFUNC(Split)
JSFUNC(Merge)
JSFUNC(EqualizeHist)
JSFUNC(Pixel)
JSFUNC(FloodFill)
/*
static Handle<Value> Val(const Arguments& args);
static Handle<Value> RowRange(const Arguments& args);
+28 -1
Ver Arquivo
@@ -190,7 +190,34 @@ vows.describe('Smoke Tests OpenCV').addBatch({
}
}
, ".absDiff and .countNonZero" : function(cv) {
cv.readImage("./examples/mona.png", function(err, im) {
cv.readImage("./examples/mona.png", function(err, im2){
assert.ok(im);
assert.ok(im2);
var diff = new cv.Matrix(im.width(), im.height());
diff.absDiff(im, im2);
diff.convertGrayscale();
assert.equal(diff.countNonZero(), 0);
});
});
}
, ".bitwiseXor" : function(cv) {
var mat1 = new cv.Matrix(1,1);
mat1.set(0,0, 1);
var mat2 = new cv.Matrix(1,1);
mat2.set(0,0, 1);
var xored = new cv.Matrix(1,1);
xored.bitwiseXor(mat1, mat2);
assert.equal(xored.get(0,0), 0);
}
}