Otsu thresholding for depth image

前端 未结 1 1386
你的背包
你的背包 2020-12-15 23:51

I am trying to substract background from depth images acquired with kinect. When I learned what otsu thresholding is I thought that it could with it. Converting the depth im

相关标签:
1条回答
  • 2020-12-16 00:08

    Otsu is probably good enough for what you are trying to do, but you do need to mask out the zero values before computing the optimal threshold with the Otsu algorithm, otherwise the distribution of intensity values will be skewed lower than what you want.

    OpenCV does not provide a mask argument for the cv::threshold function, so you will have to remove those values yourself. I would recommend putting all the non-zero values in a 1 by N matrix, and calling the cv::threshold function with CV_THRESH_OTSU and saving the return value (which is the estimated optimal threshold), and then running the cv::threshold function again on the original image with just the CV_THRESH_BINARY flag and the computed threshold.

    Here is one possible implementation:

    // move zeros to the back of a temp array
    cv::Mat copyImg = origImg;
    uint8* ptr = copyImg.datastart;
    uint8* ptr_end = copyImg.dataend;
    while (ptr < ptr_end) {
      if (*ptr == 0) { // swap if zero
        uint8 tmp = *ptr_end;
        *ptr_end = *ptr;
        *ptr = tmp;
        ptr_end--; // make array smaller
      } else {
        ptr++;
      }
    }
    
    // make a new matrix with only valid data
    cv::Mat nz = cv::Mat(std::vector<uint8>(copyImg.datastart,ptr_end),true);
    
    // compute optimal Otsu threshold
    double thresh = cv::threshold(nz,nz,0,255,CV_THRESH_BINARY | CV_THRESH_OTSU);
    
    // apply threshold
    cv::threshold(origImg,origImg,thresh,255,CV_THRESH_BINARY_INV);
    
    0 讨论(0)
提交回复
热议问题