从OpenCV Mat应用纹理后的绿屏

时间:2016-07-18 15:18:45

标签: c++ ios opencv opengl-es

我尝试使用Open GL ES 从 OpenCv Mat渲染图像。但是,我得到一个绿屏,没有别的。

我遵循了这条管道: cv :: Mat - > CVPixelBufferRef - > CVOpenGLESTextureCacheCreateTextureFromImage - > glbindTexture。

// OpenGL Texture reference for y images.
CVOpenGLESTextureRef lumaTexture;

// OpenGL Texture reference for color images.
CVOpenGLESTextureRef chromaTexture;

// OpenGL Texture cache for the color camera.
CVOpenGLESTextureCacheRef videoTextureCache;



- (void) uploadGLColorTextureFromMat:(cv::Mat)image{
    if(image.empty()){
         NSLog(@"image empty.");
    }else{


        // Clear the previous color texture.
        if (lumaTexture)
        {
            CFRelease (lumaTexture);
            lumaTexture = NULL;
        }

        // Clear the previous color texture
        if (chromaTexture)
        {
            CFRelease (chromaTexture);
            chromaTexture = NULL;
        }

        // Displaying image with width over 1280 is an overkill. Downsample it to save bandwidth.
        while( image.cols > 2560 )
            cv::resize(image, image, cv::Size(image.cols/2,image.rows/2));


        // Allow the texture cache to do internal cleanup.
        CVOpenGLESTextureCacheFlush(_display.videoTextureCache, 0);

        int height = image.rows;
        int width = image.cols;

        // set pixel buffer attributes so we get an iosurface
        NSDictionary *pixelBufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                               [NSDictionary dictionary], kCVPixelBufferIOSurfacePropertiesKey,
                                               nil];
        // create planar pixel buffer
        CVPixelBufferRef pixelBuffer = nil;
        CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
                            (__bridge CFDictionaryRef)pixelBufferAttributes, &pixelBuffer);

        // lock pixel buffer
        CVPixelBufferLockBaseAddress(pixelBuffer, 0);

        // get image details
        size_t widthB = CVPixelBufferGetWidth(pixelBuffer);
        size_t heightB = CVPixelBufferGetHeight(pixelBuffer);

          NSLog(@"%@",(pixelBuffer));

        OSType pixelFormat = CVPixelBufferGetPixelFormatType (pixelBuffer);
        NSAssert(pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, @"YCbCr is expected!");

        // Activate the default texture unit.
        glActiveTexture (GL_TEXTURE0);
        CVReturn err;
        // Create an new Y texture from the video texture cache.
        err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,videoTextureCache,
                                                           pixelBuffer,
                                                           NULL,
                                                           GL_TEXTURE_2D,
                                                           GL_RED_EXT,
                                                           (int)widthB,
                                                           (int)heightB,
                                                           GL_RED_EXT,
                                                           GL_UNSIGNED_BYTE,
                                                           0,
                                                           lumaTexture);

        if (err) {
            NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err);
            CVPixelBufferRelease(pixelBuffer);
            return;
        }



        // Set good rendering properties for the new texture.
        glBindTexture(CVOpenGLESTextureGetTarget(lumaTexture), CVOpenGLESTextureGetName(lumaTexture));
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // Activate the default texture unit.
        glActiveTexture (GL_TEXTURE1);
        // Create an new CbCr texture from the video texture cache.
        err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
                                                           videoTextureCache,
                                                           pixelBuffer,
                                                           NULL,
                                                           GL_TEXTURE_2D,
                                                           GL_RG_EXT,
                                                           (int)widthB/2,
                                                           (int)heightB/2,
                                                           GL_RG_EXT,
                                                           GL_UNSIGNED_BYTE,
                                                           1,
                                                           &chromaTexture);

        if (err)
        {
            NSLog(@"Error with CVOpenGLESTextureCacheCreateTextureFromImage: %d", err);
            return;
        }

        // Set rendering properties for the new texture.
        glBindTexture(CVOpenGLESTextureGetTarget(chromaTexture), CVOpenGLESTextureGetName(_display.chromaTexture));
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

}

要渲染的功能:

- (void)renderCameraImage
{
    if (_useColorCamera)
    {
        if (!lumaTexture || !chromaTexture)
            return;

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(CVOpenGLESTextureGetTarget(lumaTexture),
                      CVOpenGLESTextureGetName(lumaTexture));

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(CVOpenGLESTextureGetTarget(chromaTexture),
                      CVOpenGLESTextureGetName(chromaTexture));

        glDisable(GL_BLEND);
        [yCbCrTextureShader useShaderProgram];
        [yCbCrTextureShader renderWithLumaTexture:GL_TEXTURE0 chromaTexture:GL_TEXTURE1];
    }
    else
    {

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, _display.depthAsRgbaTexture);
        [rgbaTextureShader useShaderProgram];
        [rgbaTextureShader renderTexture:GL_TEXTURE0];
    }
    glUseProgram (0);

}

我没有任何错误。刚拿到绿屏,我没弄明白如何解决这个问题。 作为pixelBuffer的输出,我得到(第一行):

<CVPixelBuffer 0x13e6cd0b0 width=968 height=1296 pixelFormat=420f iosurface=0x140500a28 planes=2>
<Plane 0 width=968 height=1296 bytesPerRow=976>
<Plane 1 width=484 height=648 bytesPerRow=976>

我已经在this postthis one和其他帖子上了,但它对我没有帮助。

你能帮忙弄明白如何解决这个问题吗?

0 个答案:

没有答案