2017-09-19 6 views
2

iOS AVCaptureSesion에서 샘플 버퍼를 읽고 간단한 이미지 조작을 수행 한 다음 결과 이미지에서 픽셀을 분석합니다. 이미지 처리를 위해 openCV를 사용하여이 작업을 수행했지만 핵심 이미지로 전환하고 싶습니다.이 간단한 작업에보다 효율적으로 사용할 수 있기를 바랍니다. 그러나 나는 결과 CIImage에서 픽셀 값을 읽는 방법에 완전히 집착하고 있습니다.어떻게 CMSampleBuffer 데이터에서 생성 된 CIImage에서 픽셀 값을 효율적으로 읽을 수 있습니까?

CGImage로 백업 된 UIImage를 사용할 때 cgImage dataProvider를 사용하여 기본 픽셀 데이터에 액세스 할 수 있습니다 (아래 예 참조). CIImage의 아날로그는 무엇입니까? (수백 각 프레임에 대한 두 번째의 좋은 부분을 복용했다 - 나는 다음과 같이의 CGImage가있는 UIImage를 백업받을 CIContext를 사용하여 시도

// Getting sample video data 
    var session : AVCaptureSession = AVCaptureSession() 

    // processing the sample buffer with core image 
    func handleSampleBuffer(sampleBuffer: CMSampleBuffer) 
    {  
     let cvImage: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! 
     let ciImage: CIImage = CIImage(cvPixelBuffer: cvImage) 

     let filteredImage = processWithCoreImage(image: ciImage) 

     // 
    // How can I efficiently get pixel values from filtered image here? 
     // 
    } 

    func processWithCoreImage(image: CIImage) -> CIImage 
    { 
     // process with a core image filter chain 
     let filter1 = CIFilter(name: “…”)! 
     filter1.setValue(image, forKey: kCIInputImageKey) 
     filter1.setValue(…, forKey: …) 
     … 
     let outputImage = filter.outputImage 
     return outputImage 
    } 

    // With a regular UIImage I was doing something like this to get pixel data 
    // However CIImage does not have a cgImage backing it in this case. 
    public extension UIImage { 
     func getPixelValueGrayscale(x: Int, y: Int) -> UInt8 { 
      let pixelData = self.cgImage!.dataProvider!.data 
      let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData) 
      let pixelInfo: Int = ((Int(self.size.width) * Int(y)) + Int(x)) 
      return data[pixelInfo] 
     }  
    } 

하지만,이 끔찍하게 비효율적 증명 : 여기

내 일반적인 흐름이다 해당하는 openCV 작업보다 긴 시간).

// re-used CIContext 
let cgImage = context.createCGImage(filteredImage, from: ciImage.extent) 
let img = UIImage(cgImage: cgImage!) 

필자의 필터링 된 이미지는 작아야한다는 것을 명심해야합니다. 이것이 어떤 문제를 일으키는 지 모르겠습니다.

무엇이 누락 되었습니까? 감사.

업데이트 : 몇 가지 실험을 한 후 CI의 확장 옵션이 OpenCV에서 사용할 수있는 것보다 훨씬 느립니다. OpenCV를 확장하기 위해 프로젝트에만 포함시키는 것은 잘못되었습니다.

+0

나는 정말 대답하지 않았지만 (미안) @matt에서 "대답"에 대해 찬성표를 던졌다. 카메라로 "실시간"으로 작업하기를 원하는 것 같습니다. (그는 정확했다. 이것은 효율적인 방법이 아니다.) 나는 전문가는 아니지만 여기에있는 사람과 연결된다 : http://flexmonkey.blogspot.com/2015/12/cartooneyes-compositing-cartoon- eyes.html? view = 잡지. 해당 링크가 작동하지 않으면? 나머지 블로그 게시물을보세요. * 기술적으로 * 당신은 CI를 사용하고 싶습니다. 단지 게시 한 방식이 아닙니다. (이탤릭체를 사용하여 죄송합니다. 강조하려고합니다.) – dfd

+0

다시 신고 해 주셔서 감사합니다. 나는 이것이 어떻게 밝혀 졌는지 궁금했다. 자신의 질문에 자유롭게 답해 주시고 (심지어 며칠 후) 자신의 대답을 수락하십시오. – matt

답변

1

그러나 나는 결과 CIImage

개념은 의미가에서 픽셀 값을 읽는 방법에 완전히 붙어입니다. CIImage에는 픽셀 값이 없습니다. 그것은 이미지를 만들기위한 일련의 지시입니다. 그것은 코어 이미지의 포인트입니다. 렌더링 시간까지는 아무 일도 일어나지 않습니다. context.createCGImage(filteredImage, from: ciImage.extent)라고 말하면 은 렌더링 시간이이며 시간이 많이 걸리고 계산이 많이 소요되는 작업입니다.

+0

그럼, 아마도 잘못 말하고 있지만 질문은 남아 있습니다 : 어떻게 효율적으로 필터 체인에 의해 렌더링 된 픽셀 데이터를 얻을 수 있습니까? 위의 호출이 정확하다면, 나는 광란하게 느리기 때문에 다른 것을 잘못하고있을 것입니다. 내일 작업 예제 프로젝트를 게시하려고합니다. –