0

I have a code that detects objects in real-time, however, these objects are reloaded almost every frame, causing a huge amount of data. I want to find a way to detect the objects without having to reload the frame every second. I've attached some code snippet below which shows how the table view is loaded.

Just for note the prediction is an array of type [VNRecognizedObjectObservation]

//   var predictions: [VNRecognizedObjectObservation] = []


        extension ViewController {
        func predictUsingVision(pixelBuffer: CVPixelBuffer) {
            guard let request = request else { fatalError() }
            // vision framework configures the input size of image following our model's input configuration automatically
            self.semaphore.wait()
            let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer)
            try? handler.perform([request])
        }
        
        // MARK: - Post-processing
        func visionRequestDidComplete(request: VNRequest, error: Error?) {
            self.measure.labell(with: "endInference")
            if let predictions = request.results as? [VNRecognizedObjectObservation] {
    //            print(predictions.first?.labels.first?.identifier ?? "nil")
    //            print(predictions.first?.labels.first?.confidence ?? -1)
                
                let pred = request.results?.first
    //            print(pred)
    //            print(predictions.first?.labels.first?.identifier as Any)
                
    //            print(predictions)
     
                // This is where the table is being loaded each frame. 
                self.predictions = predictions
                DispatchQueue.main.async {
                    self.boxesView.predictedObjects = predictions
                    self.labelsTableView.reloadData()
    
                    // end of measure
                    self.measure.end()
                    
                    self.isInferencing = false
                }
            } else {
                // end of measure
                self.measure.end()
                
                self.isInferencing = false
            }
            self.semaphore.signal()
        }
    }
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
tamerjar
  • 220
  • 2
  • 12
  • First of all don’t use semaphores to force asynchronous tasks to become synchronous. Learn to understand the behavior of asynchronous data processing. UiTableView provides an API to reload single rows. But for your purpose the diffable data source might be more reasonable. – vadian Feb 28 '21 at 09:47
  • Thanks for the response, would you be able to provide with a sample code of how this works? As im quite fairly new in IOS development, and im quite unfamiliar with some terms. – tamerjar Feb 28 '21 at 10:05
  • I'm not familiar with the `VNRecognizedObjectObservation` API. This is the method to reload single rows: [reloadRows(at:with:)](https://developer.apple.com/documentation/uikit/uitableview/1614935-reloadrows) and [UITableViewDiffableDataSource](https://developer.apple.com/documentation/uikit/uitableviewdiffabledatasource) – vadian Feb 28 '21 at 10:16

2 Answers2

0

I'm not getting into the semaphores discussion, if you want to know how to update just 1 cell of a tableview you would need to know which cell obviously, identified by it's IndexPath and then update it via that route

    let indexPath = IndexPath(row: 0, section: 0)
    tableView.reloadRows(at: [indexPath], with: .fade)

This code updates the 1st cell in the 1st section of the tableview, you would need to set

row: 0

and

section: 0

with the correct values for the tableview cell you wish to update.

Dharman
  • 30,962
  • 25
  • 85
  • 135
latenitecoder
  • 746
  • 7
  • 13
0

If you know which index to reload, you can use the following function:

tableView.reloadRows(at: [indexPath], with: .none)

To reload everything but keep the offset, you can use this function:

let contentOffset = tableView.contentOffset
tableView.reloadData()
tableView.setContentOffset(contentOffset, animated: false)
INFINITE
  • 66
  • 6