2016-03-20 13 views
20

Tôi đang cố gắng lấy các điểm góc từ hình ảnh tĩnh bằng cách sử dụng GPUImageHarrisCornerDetectionFilter.Cách lấy các góc bằng cách sử dụng GPUImageHarrisCornerDetectionFilter

Tôi đã xem xét các mã ví dụ từ dự án, tôi đã xem xét các tài liệu, và tôi đã nhìn bài này đó là về những điều tương tự: GPUImage Harris Corner Detection on an existing UIImage gives a black screen output

Nhưng tôi không thể làm cho nó hoạt - và tôi có một thời gian khó hiểu làm thế nào điều này là nghĩa vụ phải làm việc với hình ảnh tĩnh.

Những gì tôi có vào thời điểm này đây là:

func harrisCorners() -> [CGPoint] { 
    var points = [CGPoint]() 

    let stillImageSource: GPUImagePicture = GPUImagePicture(image: self.image) 
    let filter = GPUImageHarrisCornerDetectionFilter() 

    filter.cornersDetectedBlock = { (cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in 
     for index in 0..<Int(cornersDetected) { 
      points.append(CGPoint(x:CGFloat(cornerArray[index * 2]), y:CGFloat(cornerArray[(index * 2) + 1]))) 
     } 
    } 

    filter.forceProcessingAtSize(self.image.size) 
    stillImageSource.addTarget(filter) 
    stillImageSource.processImage() 

    return points 
} 

Chức năng này luôn trả về [] vì vậy nó rõ ràng không phải làm việc.

Một chi tiết thú vị - tôi đã biên soạn dự án FilterShowcaseSwift từ ví dụ GPUImage và bộ lọc không tìm thấy các góc rất rõ ràng, như trên một tờ giấy trên nền đen.

+1

Do thiếu góc tìm kiếm rõ ràng, đầu dò góc Harris không phải là bất biến quy mô, vì vậy độ phân giải hình ảnh càng cao, góc sẽ càng sắc nét hơn. Các 'blurRadiusInPixels',' độ nhạy' và 'ngưỡng' có thể được tinh chỉnh ở độ phân giải đã cho để kéo ra nhiều góc hơn hoặc ít hơn, nhưng bạn cũng có thể thử nghiệm với việc giảm độ phân giải của hình ảnh đi vào máy dò để chúng thu được lớn hơn- góc tỷ lệ. Việc triển khai hiện tại cũng bị giới hạn ở mức tối đa 256 góc, vì vậy nếu tất cả những điều này được phát hiện ở phía trên bên trái của hình ảnh, sẽ không có báo cáo nào khác được báo cáo. –

Trả lời

4
filter.cornersDetectedBlock = { (cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in 
    for index in 0..<Int(cornersDetected) { 
     points.append(CGPoint(x:CGFloat(cornerArray[index * 2]), y:CGFloat(cornerArray[(index * 2) + 1]))) 
    } 
} 

Mã này bạn có ở đây đặt một khối được gọi là mọi khung hình.

Đây là quá trình không đồng bộ, do đó khi hàm của bạn trả về chưa bao giờ được gọi và mảng phải của bạn luôn trống. Nó sẽ được gọi sau khi khung đã xử lý xong.

Để xác minh điều này, hãy đặt điểm ngắt bên trong khối đó và xem nó có được gọi hay không.

Cảnh báo từ Brad Larson (tác giả của GPUImage) trong các ý kiến:

Các GPUImage bạn tạo ở đây stillImageSource sẽ được deallocated sau khi chức năng này thoát và có thể gây ra tai nạn trong trường hợp này.

+0

Vâng, điều này đúng. Tôi thực sự đã thử in các điểm từ bên trong vòng lặp tại một thời điểm, tuy nhiên bộ lọc không phát hiện được các góc trong hình ảnh thử nghiệm mà tôi đang sử dụng, vì vậy tôi đã bỏ lỡ điều đó. – henrikstroem

+1

Về mặt kỹ thuật, điều này được gọi sau bất kỳ khung được xử lý nào, dù có phát hiện được góc nào hay không. Bạn nói đúng rằng phương thức -processImage của GPUImagePicture kích hoạt một công việc xử lý trên một hàng đợi gửi nền, rất có thể sẽ không hoàn thành trước khi chức năng này thoát. Điều đó cũng có nghĩa là GPUImagePicture được định nghĩa cục bộ trong chức năng này sẽ được deallocated trước khi xử lý xong, có thể dẫn đến sự cố nếu bạn không cẩn thận. Tôi đã có một phiên bản đồng bộ của hoạt động này một lần, nhưng không nhớ tại sao tôi đã xóa nó. Deadlocks, có thể? –

+0

Cảm ơn bạn đã ghé qua bằng cách làm rõ @BradLarson! Tôi đã cập nhật một số thông tin bạn đã cung cấp. :] – Jack

Các vấn đề liên quan