Comparar commits
70 Commits
thresholds
...
master
| Autor | SHA1 | Data | |
|---|---|---|---|
| e3b20082ab | |||
| fbb030e571 | |||
| 1c96622c67 | |||
| 77a6d19c3b | |||
| e00f24b3e4 | |||
| d75f437b73 | |||
| a6d6be2d7d | |||
| 52e03bb7f3 | |||
| 9e0367e9f9 | |||
| 22c86364c7 | |||
| 5a3cc35d25 | |||
| 73c47177e2 | |||
| fc518a1459 | |||
| db3322ebcd | |||
| c7ae7140ea | |||
| 1d9072aefb | |||
| 6f9f38112b | |||
| f66364f1bb | |||
| 0d53c15058 | |||
| bbf36e72b1 | |||
| b79c30069f | |||
| fddd01a3d1 | |||
| dd5961cfe2 | |||
| 2c5324df41 | |||
| 0520e6dcea | |||
| 612d0f1c21 | |||
| 65d9e3ea99 | |||
| 824ffceeb2 | |||
| 5daf9c0f4d | |||
| 187b6d073a | |||
| 146925ee6d | |||
| e7300b1cfc | |||
| e0c4d42503 | |||
| b2ed603a2a | |||
| 3105e14f25 | |||
| 276e42bffc | |||
| ce742ecce2 | |||
| 6bdaa3a24f | |||
| cceea7b498 | |||
| d60e3d11d5 | |||
| 363b950f1e | |||
| 813e5ee55f | |||
| 852de17b47 | |||
| a190298eaf | |||
| 4ce14beb96 | |||
| b8ec62e5f8 | |||
| 03a00c062f | |||
| d9f0b16f16 | |||
| 7ea1435491 | |||
| 13488fa94b | |||
| 85e1ce2448 | |||
| 3b4c361f5c | |||
| 5eb7e836c3 | |||
| abb20798c3 | |||
| 7548d39616 | |||
| 762ac42f3b | |||
| 27f722e6aa | |||
| 1e5a0f2a23 | |||
| 4cc5eff25b | |||
| c93cfb782b | |||
| bce9d95c29 | |||
| 25bec10b28 | |||
| f5df8f6599 | |||
| f6ff1e58b5 | |||
| e507377a80 | |||
| aa7b3317fe | |||
| 7b3835bbf5 | |||
| c3d1379cd5 | |||
| c4a20bb279 | |||
| cca52ad691 |
@@ -4,4 +4,5 @@ build
|
||||
node_modules
|
||||
npm-debug.log
|
||||
out*.jpg
|
||||
out*.png
|
||||
examples/*.avi
|
||||
|
||||
+101
-79
@@ -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
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
@@ -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 |
Arquivo executável
BIN
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 518 KiB |
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 50 KiB |
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 --
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário