Skip to content

Instantly share code, notes, and snippets.

@GabiThume
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GabiThume/335eabfc5fd440242b89 to your computer and use it in GitHub Desktop.
Save GabiThume/335eabfc5fd440242b89 to your computer and use it in GitHub Desktop.
noflo = require 'noflo'
unless noflo.isBrowser()
chai = require 'chai' unless chai
GetCannyEdges = require '../components/GetCannyEdges.coffee'
testutils = require './testutils'
else
GetCannyEdges = require 'noflo-image/components/GetCannyEdges.js'
testutils = require 'noflo-image/spec/testutils.js'
describe 'GetCannyEdges component', ->
c = null
inImage = null
low = null
high = null
kernel = null
outImage = null
beforeEach ->
c = GetCannyEdges.getComponent()
inImage = noflo.internalSocket.createSocket()
low = noflo.internalSocket.createSocket()
high = noflo.internalSocket.createSocket()
kernel = noflo.internalSocket.createSocket()
outImage = noflo.internalSocket.createSocket()
c.inPorts.image.attach inImage
c.inPorts.low.attach low
c.inPorts.high.attach high
c.inPorts.kernel.attach kernel
c.outPorts.image.attach outImage
describe 'when instantiated', ->
it 'should have four input ports', ->
chai.expect(c.inPorts.image).to.be.an 'object'
chai.expect(c.inPorts.low).to.be.an 'object'
chai.expect(c.inPorts.high).to.be.an 'object'
chai.expect(c.inPorts.kernel).to.be.an 'object'
it 'should have one output port', ->
chai.expect(c.outPorts.image).to.be.an 'object'
describe 'with file system image', ->
it 'should make an image with edges', (done) ->
@timeout 10000
outImage.once 'data', (data) ->
chai.expect(data).to.be.an 'object'
outSrc = 'extract-small-canny.png'
id = testutils.getCanvasWithImage outSrc, (outImage) =>
ctx = data.getContext '2d'
testImageData = ctx.getImageData(0, 0, data.width, data.height).data
ctx_ = outImage.getContext '2d'
outImageData = ctx_.getImageData(0, 0, outImage.width, outImage.height).data
for x in [0...testImageData.length] by 4
chai.expect(testImageData[x]).to.equal outImageData[x]
done()
inSrc = 'extract-small.png'
id = testutils.getCanvasWithImage inSrc, (image) ->
inImage.send image
noflo = require 'noflo'
jsfeat = require 'jsfeat'
if noflo.isBrowser()
requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
(callback, element) ->
window.setTimeout( ->
callback(+new Date())
, 1000 / 60)
class GetCannyEdges extends noflo.Component
description: 'Canny edge detector.'
icon: 'file-image-o'
constructor: ->
@low = 20
@high = 50
@kernel = 6
@image = null
@running = false
@inPorts =
image: new noflo.Port 'object'
low: new noflo.Port 'number'
high: new noflo.Port 'number'
kernel: new noflo.Port 'number'
@outPorts =
image: new noflo.Port 'object'
@inPorts.image.on 'data', (image) =>
@running = true
@image = image
@computeCanny()
@inPorts.low.on 'data', (low) =>
@low = low
@computeCanny()
@inPorts.high.on 'data', (high) =>
@high = high
@computeCanny()
@inPorts.kernel.on 'data', (kernel) =>
@kernel = kernel
@computeCanny()
computeCanny: ->
return unless @outPorts.image.isAttached()
return unless @image
if @image.tagName? and @image.tagName is 'VIDEO'
requestAnimationFrame @computeCanny.bind(@)
image = @image
if noflo.isBrowser()
canvas = document.createElement 'canvas'
canvas.width = image.width
canvas.height = image.height
else
Canvas = require 'canvas'
canvas = new Canvas image.width, image.height
context = canvas.getContext '2d'
context.drawImage image, 0, 0
img = context.getImageData 0, 0, canvas.width, canvas.height
img_u8 = new jsfeat.matrix_t canvas.width, canvas.height, jsfeat.U8_t|jsfeat.C1_t
jsfeat.imgproc.grayscale img.data, img_u8.data
jsfeat.imgproc.gaussian_blur img_u8, img_u8, @kernel, 0
jsfeat.imgproc.canny img_u8, img_u8, @low, @high
### *** HERE!!! *** img doesn't has .buffer attr in node-canvas! *** ###
img_u32 = new Uint32Array img.data.buffer
# A possible solution, but doesn't works neither:
if not noflo.isBrowser()
img_u32 = new Canvas.PixelArray canvas, 0, 0, image.width, image.height
alpha = (0xff << 24)
i = img_u8.cols*img_u8.rows
pix = 0
while --i >= 0
pix = img_u8.data[i]
img_u32[i] = alpha | (pix << 16) | (pix << 8) | pix
context.putImageData img, 0, 0
@outPorts.image.send canvas
exports.getComponent = -> new GetCannyEdges
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment