如何在Tensorflow.js中计算Laplacian?

时间:2019-04-09 16:15:27

标签: javascript tensorflow.js

我目前正在尝试设计一个Node.js代码,该代码可以判断图像是否模糊。为了实现这一目标,我汲取了灵感from this question。因此,我需要做的是计算矩阵拉普拉斯矩阵(就是我们所说的?),然后计算方差。

使用OpenCV(使用opencv4nodejs)可以做到这一点:

# load image
_cvImg = cv.imread _file

# get grayscale image
_cvImgGray =_cvImg.bgrToGray()

# Compute laplacian
_laplacian = _cvImgGray.laplacian(cv.CV_8U)

# Get the standard deviation
_meanStdDev = _laplacian.meanStdDev()

_stddevarray = _meanStdDev.stddev.getDataAsArray()
_stdDeviation = _stddevarray[0]

# Get the variation
_variation = Math.pow(_stdDeviation, 2)

但是现在,我正在使用Tensorflow.js,这确实不那么容易...这是我尝试做的事情:

# load image
_cvImg = cv.imread _file

#convert frame to a tensor
try
    _data = new Uint8Array(_frame.cvtColor(cv.COLOR_BGR2RGB).getData().buffer)
    _tensorFrame = tfjs.tensor3d(_data, [_frame.rows, _frame.cols, 3])
catch _err
    @log.error "Error instantiating tensor !!!"
    @log.error _err.message

# get grayscale image
_grayscaleFrame = _tensorFrame.mean(2).expandDims(2)

# prepare convolution to get laplacian
laplaceFilter = tfjs.tensor2d([[0,1,0], [1,-4,1], [0,1,0]])
laplaceFilter3D = laplaceFilter.expandDims(2)

# get laplacian
_laplacian = tfjs.conv1d _tensorFrame, laplaceFilter3D, 1, 'same'

# get standard deviation
_standardDeviation = tfjs.moments(_laplacian2).variance.buffer().values[0]

# get variance
_variance = _standardDeviation * _standardDeviation

# dispose tensor to avoid memeory leaks
_tensorFrame.dispose()

并不奇怪,上面的代码不起作用。我知道我的卷积应该是二维(tf.conv2d)而不是一维(tf.conv1d),因为我正在处理图像。如果我查看tf.conv2d in API,可以看到以下签名:

tf.conv2d (x, filter, strides, pad, dataFormat?, dilations?, dimRoundingMode?) 

并且filter应该是tf.Tensor4D!但我不知道如何将以下过滤矩阵转换为tf.Tensor4D

    1
1   4   1   
    1

我做错什么了吗?如何在Tensorflow.js中获得矩阵的拉普拉斯算子?即我如何在代表我的图像的tensor2d和上面的过滤器之间进行简单的卷积?

2 个答案:

答案 0 :(得分:0)

可以通过首先扩展其尺寸在2d张量上执行卷积。同样,对于使用tf.reshape

的过滤器

计算后,tf.squeeze将删除形状1的尺寸,从而返回2d张量

const x = tf.tensor2d(Array.from({length: 16}, (_, k) => k+1), [4, 4]); // input image 2d

const filter = tf.tensor2d([0, 1, 0, 1, 0, 1, 0, 1, 0], [3, 3]) // input filter 2d

x.reshape([1, ...x.shape, 1]).conv2d(filter.reshape([...filter.shape, 1, 1]), 1, 'valid').squeeze().print() // conv
<html>
  <head>
    <!-- Load TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.14.1"> </script>
  </head>

  <body>
  </body>
</html>

答案 1 :(得分:0)

另一种解决方案:

// Reads the image, converts to gray and makes shape (1, width, height, 1) [batch, in_height, in_width, in_channels]
let _grayscaleFrame = tf.browser.fromPixels(canvas).mean(2).toFloat().expandDims(0).expandDims(-1); 
                                                          

// prepare convolution to get laplacian
let laplaceFilter = tf.tensor2d([
          [0, 1, 0],
          [1, -4, 1],
          [0, 1, 0]
]).expandDims(-1).expandDims(-1); // [filter_height, filter_width, in_channels, out_channels]

// get laplacian
let _laplacian = _grayscaleFrame.conv2d(laplaceFilter, 1, 'valid').squeeze()