【问题标题】:How to create a Racket mutable array from a C pointer to modify an OpenCV image?如何从 C 指针创建 Racket 可变数组以修改 OpenCV 图像?
【发布时间】:2020-01-13 21:49:35
【问题描述】:

我正在玩这些OpenCV bindings for Racket,我希望能够以数组的形式访问像素值,主要是为了可以使用行列索引。示例仅显示如何调用高级 OpenCV 函数,然后访问原始数据仅通过对bytestring 的低级访问显示。

一切都很好,我印象深刻。对于某些应用程序,我们认为,我们应该能够进行一些逐像素处理,理想情况下利用 Racket 中的本机多维数组对象,这似乎是math:array。问题是如何从IplImage 对象创建这个可变数组。

我能够运行 bytestring 示例,这已经不理想了,因为它不支持其他类型,例如 float。以下代码用于从指向图像数据的指针中创建一个cvector

(define xx (make-cvector* (IplImage-imageData frame) ffi:_uint8 307200))
(cvector-set! xx ii 255)
(set! ii (ii . + . 1) )

这会在循环内的每一帧绘制一个像素移动......这很有效。现在我想用这个cvector 创建一个数组。我想出了以下代码:

(define (image->array image)
  (let ([data
         (make-cvector* (IplImage-imageData image)
                        ffi:_uint8
                        (IplImage-imageSize image))]
        [shape (vector (IplImage-height image) (IplImage-width image))])
    (array->mutable-array (list->array
                           shape
                           (cvector->list data)))))

这显然适用于阅读,但不适用于回写。我如何使它实际上是可变的?这里有任何性能问题吗? cvector->list 是否可能将所有数据复制到新的球拍列表中?如何创建math:array 可以使用的球拍矢量对象?

【问题讨论】:

  • “不支持...浮动”是什么意思?你能举个例子说明你想用花车做什么吗?
  • cvector->list 将复制向量的内容。 list->array 将再次复制它们,array->mutable-array 将再复制一份。如果您想要修改原始数组位的访问器,将其视为二维对象,我怀疑您需要编写它们。
  • @adatzer 许多应用程序表示深度大于 8 位的图像,以及定点和浮点类型。 OpenCV 支持很多这样的类型,更不用说通道了。
  • @tfb 好吧,处理维度的工作是由数组函数完成的,它们似乎不接受 cvector 而不是向量,我需要什么来实现这个看似简单的界面同时防止复制?
  • 正如我所说,您可能需要编写它们:math/array 绝对不是您想要的,因为如果它们是可变的,这些数组希望管理自己的存储。

标签: arrays opencv lisp racket ffi


【解决方案1】:

您的代码确实返回了一个可变数组。只是它只适用于灰度图像,因为list->array 需要一个长度列表(* 宽度高度),而cvector->list 返回一个长度列表(* 宽度高度通道)。一路走来: cpointer >> cvector >> list >> immutable-array >> mutable-array 只是为了有行列索引似乎有点太多了,因为你可以定义一个函数来“模拟”你想要的访问风格.

关于性能问题,请参阅这个 StackOverflow 问题[1](由 racket-opencv 的创建者提供),它解释了 bytestrings 和 IplImage-data 函数背后的原因。您已经提到字节串对您来说并不理想,但是即使您必须使用向量(或数学/数组),也请尝试以下方式:cpointer >> bytestring >> list >> vector(在我的机器上更快) .

[1]Fast array access using Racket FFI

【讨论】:

  • 嗯,我当然不想想要有很多麻烦。我想重用构建在数组之上的现有函数,使用 cvectors 作为后端。我正在寻找最简单的方法,或者弄清楚如何从任何类型的 cvector 创建一个向量。顺便说一下,(mutable-array (immutable-array ...)) 就是我理解的在Racket中创建不可变数组的正常方式,而且抽象的操作显然很简单,不是这里真正的问题。跨度>
猜你喜欢
  • 2021-03-05
  • 1970-01-01
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 2011-09-23
相关资源
最近更新 更多