Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 我怎样才能在图像中找到最亮的点(可能是金属)?_Ios_Metal_Core Image_Metal Performance Shaders - Fatal编程技术网

Ios 我怎样才能在图像中找到最亮的点(可能是金属)?

Ios 我怎样才能在图像中找到最亮的点(可能是金属)?,ios,metal,core-image,metal-performance-shaders,Ios,Metal,Core Image,Metal Performance Shaders,我用金属制作了一个定制的内核。这很有用,因为它接近实时。我正在避免任何可能会实时延迟的cgcontext或cicontext。我的内核基本上做了Hough变换,但我似乎不知道如何从图像缓冲区读取白点 下面是kernel.metal: #include <CoreImage/CoreImage.h> extern "C" { namespace coreimage { float4 hough(sampler src) { // M

我用金属制作了一个定制的内核。这很有用,因为它接近实时。我正在避免任何可能会实时延迟的cgcontext或cicontext。我的内核基本上做了Hough变换,但我似乎不知道如何从图像缓冲区读取白点

下面是kernel.metal:

#include <CoreImage/CoreImage.h>

extern "C" {
    namespace coreimage {

        float4 hough(sampler src) {

            // Math

            // More Math

            // eventually:

            if (luminance > 0.8) {
                uint2 position = src.coord()
                // Somehow add this to an array because I need to know the x,y pair
            }

            return float4(luminance, luminance, luminance, 1.0);
        }
    }
}
这不会给出亮度大于0.8的每个像素,但对于我来说,它返回的足够多:每列中的最高值及其位置

优点:只将(2*图像宽度)字节复制到CPU,而不是每个像素,可以节省大量时间(几毫秒)

缺点:如果你在同一列中有两个主要的白点,你永远不会知道。如果这符合您的用例,您可能必须修改它并按行而不是按列进行计算

跟进:

呈现输出时似乎有问题。以金属形式返回的浮点值与我在swift中获得的UInt8值不相关

描述问题


编辑:提供了非常方便的金属功能。当您对金属值(例如0.5)调用它并返回它时,您将在CPU上获得正确的值(例如128)。

查看
类别还原中的过滤器(如)。它们返回的图像只有几个像素高,包含缩小结果。但是您仍然需要渲染它们才能读取Swift函数中的值

使用这种方法解决问题的问题是,您不知道事先返回的坐标数。不过,当核心映像调用内核时,它需要知道输出的扩展。你可以假设一个静态的最大坐标数,但这听起来很乏味

我认为您最好使用在CPU上迭代图像像素(并行化,超级高效)以找到相应的坐标


你可以做一个混合的方法,在GPU上用核心图像做每像素重的数学运算,然后在CPU上用Accelerate做分析。您甚至可以使用集成处理器将CPU部件集成到核心映像管道中。

谢谢!我尝试过Accelerate和CiImageProcessornel,这涉及到将像素复制到内存中,这使我的相机速度下降到了11fps左右(我的目标是至少30帧)。我很好奇CICategoryReduction的底层内核是什么样子的。不确定内置是否适合我的需要,但我可能可以做一个。因为GPU和CPU内存在iOS中共享,所以不需要复制数据。从
ciimageprocessornel
CIImageProcessorInput
中,您可以获取输入图像的底层数据缓冲区的
基址
,并直接使用Accelerate对其进行操作。您能再解释一下如何读取CPU中的字节吗?我用的是
.getBytes()
,速度慢了很多。在文档中,“核心映像将网络中的过滤器连接成尽可能少的内核,避免创建中间缓冲区。但是,它无法使用映像处理器内核实现这一点。”我认为这也可能是一个问题。考虑到这一点,我想你也不能真正使用
ciimageprocessornel
,因为你不知道结果的数量。不知何故,您需要将最终的
CIImage
渲染到您可以使用Accelerate访问的一些数据缓冲区中(例如使用
CIContext.render(CIImage,toBitmap:UnsafeMutableRawPointer,rowBytes:Int,bounds:CGRect,format:CIFormat,colorSpace:CGColorSpace?
)。你可以说你的图像最初从哪里来,你需要结果到哪里去(例如,如果需要进一步的处理)?你对srgba到线性有什么见解,因为我读取的值与我的内核返回的值不同吗
    /// Returns the maximum value in each column.
    ///
    /// - Parameter src: a sampler for the input texture
    /// - Returns: maximum value in for column
    float4 maxValueForColumn(sampler src) {

        const float2 size = float2(src.extent().z, src.extent().w);

        /// Destination pixel coordinate, normalized
        const float2 pos = src.coord();

        float maxV = 0;

        for (float y = 0; y < size.y; y++) {
            float v = src.sample(float2(pos.x, y / size.y)).x;
            if (v > maxV) {
                maxV = v;
            }
        }

        return float4(maxV, maxV, maxV, 1.0);
    }

    /// Returns the normalized coordinate of the maximum value in each column.
    ///
    /// - Parameter src: a sampler for the input texture
    /// - Returns: normalized y-coordinate of the maximum value in for column
    float4 maxCoordForColumn(sampler src) {

        const float2 size = float2(src.extent().z, src.extent().w);

        /// Destination pixel coordinate, normalized
        const float2 pos = src.coord();

        float maxV = 0;
        float maxY = 0;

        for (float y = 0; y < size.y; y++) {
            float v = src.sample(float2(pos.x, y / size.y)).x;
            if (v > maxV) {
                maxY = y / size.y;
                maxV = v;
            }
        }

        return float4(maxY, maxY, maxY, 1.0);
    }