houxiao
2017-08-01 ab5f950eb26752a7a26ea746dd22a41a00b1074a
RtspFace/PL_BlockGrouping.cpp
@@ -20,30 +20,30 @@
   MBFrameWrapper(bool _copyData, const MB_Frame _frame) :
      frame(_frame), frameRefCount(_copyData ? 0 : -1)
   {
        if (_copyData)
        {
            uint8_t* newBuffer = new uint8_t[_frame.buffSize];
            frame.buffer = newBuffer;
            memcpy(newBuffer, _frame.buffer, _frame.buffSize);
        }
    }
      if (_copyData)
      {
         uint8_t* newBuffer = new uint8_t[_frame.buffSize];
         frame.buffer = newBuffer;
         memcpy(newBuffer, _frame.buffer, _frame.buffSize);
      }
   }
   void reference()
   {
       if (frameRefCount >= 0)
           frameRefCount++;
       else
           frameRefCount--;
      if (frameRefCount >= 0)
         frameRefCount++;
      else
         frameRefCount--;
   }
    void release()
    {
        if (frameRefCount == 0)
        {
            delete[] (uint8_t*)frame.buffer;
            frame.reset();
        }
        else if (frameRefCount == -1)
   void release()
   {
      if (frameRefCount == 0)
      {
         delete[] (uint8_t*)frame.buffer;
         frame.reset();
      }
      else if (frameRefCount == -1)
      {
         frame.reset();
      }
@@ -56,7 +56,7 @@
      {
         frameRefCount--;
      }
    }
   }
   
   ~MBFrameWrapper()
   {
@@ -68,7 +68,7 @@
{
   const uint16_t blockID;
    RectWrapper rectWrapper;
   RectWrapper rectWrapper;
   MBFrameWrapper* mbfWrapper;
   uint8_t* croppedData;
   size_t croppedDataSize;
@@ -81,48 +81,48 @@
      if (croppedData != nullptr || mbfWrapper == nullptr)
         return;
        PLGH_Rect& rect(rectWrapper.rect);
      PLGH_Rect& rect(rectWrapper.rect);
      if (mbfWrapper->frame.type == MB_Frame::MBFT_YUV420)
      {
            int src_width = mbfWrapper->frame.width;
            int src_height = mbfWrapper->frame.height;
            uint8_t* src_y = (uint8_t*)(mbfWrapper->frame.buffer);
            uint8_t* src_u = (uint8_t*)(src_y + (src_height * src_width));
            uint8_t* src_v = (uint8_t*)(src_u + (src_height * src_width / 4));
         int src_width = mbfWrapper->frame.width;
         int src_height = mbfWrapper->frame.height;
         uint8_t* src_y = (uint8_t*)(mbfWrapper->frame.buffer);
         uint8_t* src_u = (uint8_t*)(src_y + (src_height * src_width));
         uint8_t* src_v = (uint8_t*)(src_u + (src_height * src_width / 4));
            cv::Mat matY(cv::Size(src_width, src_height), CV_8UC1, src_y);
            cv::Mat roiMatY(matY, cv::Rect(rect.leftTop.X, rect.leftTop.Y, rect.width(), rect.height()));
            cv::Mat cloneRoiMatY(roiMatY.clone());
         cv::Mat matY(cv::Size(src_width, src_height), CV_8UC1, src_y);
         cv::Mat roiMatY(matY, cv::Rect(rect.leftTop.X, rect.leftTop.Y, rect.width(), rect.height()));
         cv::Mat cloneRoiMatY(roiMatY.clone());
            cv::Mat matU(cv::Size(MH_SUBSAMPLE1(src_width, 2), MH_SUBSAMPLE1(src_height, 2)), CV_8UC1, src_u);
            cv::Mat roiMatU(matU, cv::Rect(MH_SUBSAMPLE1(rect.leftTop.X, 2), MH_SUBSAMPLE1(rect.leftTop.Y, 2), MH_SUBSAMPLE1(rect.width(), 2), MH_SUBSAMPLE1(rect.height(), 2)));
            cv::Mat cloneRoiMatU(roiMatU.clone());
         cv::Mat matU(cv::Size(MH_SUBSAMPLE1(src_width, 2), MH_SUBSAMPLE1(src_height, 2)), CV_8UC1, src_u);
         cv::Mat roiMatU(matU, cv::Rect(MH_SUBSAMPLE1(rect.leftTop.X, 2), MH_SUBSAMPLE1(rect.leftTop.Y, 2), MH_SUBSAMPLE1(rect.width(), 2), MH_SUBSAMPLE1(rect.height(), 2)));
         cv::Mat cloneRoiMatU(roiMatU.clone());
            cv::Mat matV(cv::Size(MH_SUBSAMPLE1(src_width, 2), MH_SUBSAMPLE1(src_height, 2)), CV_8UC1, src_v);
            cv::Mat roiMatV(matV, cv::Rect(MH_SUBSAMPLE1(rect.leftTop.X, 2), MH_SUBSAMPLE1(rect.leftTop.Y, 2), MH_SUBSAMPLE1(rect.width(), 2), MH_SUBSAMPLE1(rect.height(), 2)));
            cv::Mat cloneRoiMatV(roiMatV.clone());
         cv::Mat matV(cv::Size(MH_SUBSAMPLE1(src_width, 2), MH_SUBSAMPLE1(src_height, 2)), CV_8UC1, src_v);
         cv::Mat roiMatV(matV, cv::Rect(MH_SUBSAMPLE1(rect.leftTop.X, 2), MH_SUBSAMPLE1(rect.leftTop.Y, 2), MH_SUBSAMPLE1(rect.width(), 2), MH_SUBSAMPLE1(rect.height(), 2)));
         cv::Mat cloneRoiMatV(roiMatV.clone());
            const size_t yPlanarSize = rect.width() * rect.height();
            croppedDataSize = yPlanarSize * 1.5;
            croppedData = new uint8_t[croppedDataSize];
         const size_t yPlanarSize = rect.width() * rect.height();
         croppedDataSize = yPlanarSize * 1.5;
         croppedData = new uint8_t[croppedDataSize];
            uint8_t* dst_y = (uint8_t*)croppedData;
            uint8_t* dst_u = (uint8_t*)(dst_y + yPlanarSize);
            uint8_t* dst_v = (uint8_t*)(dst_u + yPlanarSize / 4);
         uint8_t* dst_y = (uint8_t*)croppedData;
         uint8_t* dst_u = (uint8_t*)(dst_y + yPlanarSize);
         uint8_t* dst_v = (uint8_t*)(dst_u + yPlanarSize / 4);
            memcpy(dst_y, cloneRoiMatY.ptr(), yPlanarSize);
            memcpy(dst_u, cloneRoiMatU.ptr(), yPlanarSize / 4);
            memcpy(dst_v, cloneRoiMatV.ptr(), yPlanarSize / 4);
         memcpy(dst_y, cloneRoiMatY.ptr(), yPlanarSize);
         memcpy(dst_u, cloneRoiMatU.ptr(), yPlanarSize / 4);
         memcpy(dst_v, cloneRoiMatV.ptr(), yPlanarSize / 4);
            //{
            //    static size_t f = 0;
            //    char fname[50];
            //    sprintf(fname, "/sdcard/face-%u-w%u-h%u.yuv420", ++f, rect.width(), rect.height());
            //    FILE *pFile = fopen(fname, "wb");
            //    fwrite(croppedData, 1, croppedDataSize, pFile);
            //    fclose(pFile);
            //    if (f > 10)exit(0);
            //}
         //{
         //   static size_t f = 0;
         //   char fname[50];
         //   sprintf(fname, "/sdcard/face-%u-w%u-h%u.yuv420", ++f, rect.width(), rect.height());
         //   FILE *pFile = fopen(fname, "wb");
         //   fwrite(croppedData, 1, croppedDataSize, pFile);
         //   fclose(pFile);
         //   if (f > 10)exit(0);
         //}
      }
      else if (mbfWrapper->frame.type == MB_Frame::MBFT_NV12)
      {
@@ -136,8 +136,8 @@
         cv::Mat cloneRoiMatY(roiMatY.clone());
         
         cv::Mat matUV(cv::Size(MH_SUBSAMPLE1(src_width, 2), MH_SUBSAMPLE1(src_height, 2)), CV_16UC1, src_uv);
            cv::Mat roiMatUV(matUV, cv::Rect(MH_SUBSAMPLE1(rect.leftTop.X, 2), MH_SUBSAMPLE1(rect.leftTop.Y, 2), MH_SUBSAMPLE1(rect.width(), 2), MH_SUBSAMPLE1(rect.height(), 2)));
            //cv::Mat roiMatUV(matUV, cv::Rect(rect.leftTop.X, rect.leftTop.Y, rect.width(), rect.height()));
         cv::Mat roiMatUV(matUV, cv::Rect(MH_SUBSAMPLE1(rect.leftTop.X, 2), MH_SUBSAMPLE1(rect.leftTop.Y, 2), MH_SUBSAMPLE1(rect.width(), 2), MH_SUBSAMPLE1(rect.height(), 2)));
         //cv::Mat roiMatUV(matUV, cv::Rect(rect.leftTop.X, rect.leftTop.Y, rect.width(), rect.height()));
         cv::Mat cloneRoiMatUV(roiMatUV.clone());
         
         const size_t yPlanarSize = rect.width() * rect.height();
@@ -161,10 +161,10 @@
   }
   
   void release_crop()
    {
        delete[] (uint8_t*)croppedData;
        croppedDataSize = 0;
    }
   {
      delete[] (uint8_t*)croppedData;
      croppedDataSize = 0;
   }
   
   ~PLBG_Block()
   {
@@ -181,8 +181,8 @@
   const uint16_t groupID;
   
   std::vector<PLBG_Block> blocks; // sequence of paid blocks
    int paid_rect_interval;
    int paid_frame_count;
   int paid_rect_interval;
   int paid_frame_count;
   int _current_frame_accepted_blocks;
   
   PLBG_Group() : groupID(++_groupID), blocks(), paid_rect_interval(0), paid_frame_count(0), _current_frame_accepted_blocks(0)
@@ -276,7 +276,7 @@
bool plbg_pay_breaker(const PipeMaterial* pm, void* args)
{
    *(PipeMaterial**)args = const_cast<PipeMaterial*>(pm);
   *(PipeMaterial**)args = const_cast<PipeMaterial*>(pm);
   return false;
}
@@ -310,7 +310,7 @@
{
   PL_BlockGrouping_Internal* in = (PL_BlockGrouping_Internal*)internal;
    //#todo
   //#todo
   //if (in->mbfs.size() + 1 >= PLBG_MAX_CACHE_FRAMES)
   //{
   //   LOG_WARN << "cached frame exceed " << PLBG_MAX_CACHE_FRAMES << LOG_ENDL;
@@ -318,35 +318,35 @@
   //}
    PipeMaterial pmPtr;
    {
        PipeMaterial* _pmPtr = nullptr;
        pm.breake(PipeMaterial::PMT_PTR, MB_Frame::MBFT__FIRST, plbg_pay_breaker, &_pmPtr);
        if (_pmPtr == nullptr)
        {
            LOG_WARN << "PMT_PM_LIST need PMT_PTR" << LOG_ENDL;
            return false;
        }
        pmPtr = *_pmPtr;
    }
   PipeMaterial pmPtr;
   {
      PipeMaterial* _pmPtr = nullptr;
      pm.breake(PipeMaterial::PMT_PTR, MB_Frame::MBFT__FIRST, plbg_pay_breaker, &_pmPtr);
      if (_pmPtr == nullptr)
      {
         LOG_WARN << "PMT_PM_LIST need PMT_PTR" << LOG_ENDL;
         return false;
      }
      pmPtr = *_pmPtr;
   }
    MB_Frame mbfFrame;
    {
        PipeMaterial* _pmFrame = nullptr;
   MB_Frame mbfFrame;
   {
      PipeMaterial* _pmFrame = nullptr;
        if (_pmFrame == nullptr)
            pm.breake(PipeMaterial::PMT_FRAME, MB_Frame::MBFT_YUV420, plbg_pay_breaker, &_pmFrame);
        if (_pmFrame == nullptr)
            pm.breake(PipeMaterial::PMT_FRAME, MB_Frame::MBFT_NV12, plbg_pay_breaker, &_pmFrame);
      if (_pmFrame == nullptr)
         pm.breake(PipeMaterial::PMT_FRAME, MB_Frame::MBFT_YUV420, plbg_pay_breaker, &_pmFrame);
      if (_pmFrame == nullptr)
         pm.breake(PipeMaterial::PMT_FRAME, MB_Frame::MBFT_NV12, plbg_pay_breaker, &_pmFrame);
        if (_pmFrame == nullptr)
        {
            LOG_WARN << "PMT_PM_LIST need PMT_FRAME of (MBFT_YUV420 or MBFT_NV12)" << LOG_ENDL;
            return false;
        }
      if (_pmFrame == nullptr)
      {
         LOG_WARN << "PMT_PM_LIST need PMT_FRAME of (MBFT_YUV420 or MBFT_NV12)" << LOG_ENDL;
         return false;
      }
        mbfFrame = *(MB_Frame*)_pmFrame->buffer;
    }
      mbfFrame = *(MB_Frame*)_pmFrame->buffer;
   }
   // cache frame
   MBFrameWrapper* mbfWrapper = new MBFrameWrapper(in->config.copyData, mbfFrame);
@@ -359,40 +359,40 @@
   for (std::list<PLBG_Group>::iterator iterGrp = in->groups.begin(); iterGrp != in->groups.end(); ++iterGrp)
   {
      PLBG_Group& currGroup(*iterGrp);
        currGroup.paid_rect_interval++;
        currGroup.paid_frame_count++;
      currGroup.paid_rect_interval++;
      currGroup.paid_frame_count++;
      for (std::list<RectWrapper>::iterator iterRectw = rectws.begin(); iterRectw != rectws.end(); )
      {
         const RectWrapper& currRectw(*iterRectw);
         if (!test_group_accept_rect(in, currGroup, currRectw.rect))
            {
                ++iterRectw;
                continue;
            }
         {
            ++iterRectw;
            continue;
         }
         
         // accept this block into group
         PLBG_Block currBlock;
         currBlock.rectWrapper = currRectw;
         currBlock.mbfWrapper = mbfWrapper;
            mbfWrapper->reference();
         mbfWrapper->reference();
         currBlock.crop_data();
         currGroup.blocks.push_back(currBlock);
            currGroup.paid_rect_interval = 0;
            currGroup._current_frame_accepted_blocks++;
         currGroup.paid_rect_interval = 0;
         currGroup._current_frame_accepted_blocks++;
            iterRectw = rectws.erase(iterRectw);
         iterRectw = rectws.erase(iterRectw);
      }
   }
    //#todo
   //#todo
   // we test remain groups asume remain rectws
   //if (in->groups.size() > PLBG_MAX_GROUPS - rectws.size())
   //{
   //   if (mbfWrapper->frameRefCount == 0)
   //   {
    //        in->mbfs.erase(mbfWrapper);
   //      in->mbfs.erase(mbfWrapper);
   //      delete mbfWrapper;
   //      mbfWrapper = nullptr;
   //   }
@@ -409,14 +409,14 @@
      PLBG_Block currBlock;
      currBlock.rectWrapper = *rectws.begin();
      currBlock.mbfWrapper = mbfWrapper;
        mbfWrapper->reference();
      mbfWrapper->reference();
      currBlock.crop_data();
      rectws.erase(rectws.begin());
      
      PLBG_Group currGroup;
      currGroup.blocks.push_back(currBlock);
        currGroup.paid_rect_interval = 0;
        currGroup._current_frame_accepted_blocks++;
      currGroup.paid_rect_interval = 0;
      currGroup._current_frame_accepted_blocks++;
      iterNewGrp = in->groups.insert(in->groups.end(), currGroup);
   }
   
@@ -435,7 +435,7 @@
      PLBG_Block currBlock;
      currBlock.rectWrapper = *iterRectw;
      currBlock.mbfWrapper = mbfWrapper;
        mbfWrapper->reference();
      mbfWrapper->reference();
      currBlock.crop_data();
      if (iterGrp == in->groups.end())
      {
@@ -452,37 +452,37 @@
   for (std::list<PLBG_Group>::iterator iterGrp = in->groups.begin(); iterGrp != in->groups.end(); ++iterGrp)
      iterGrp->_current_frame_accepted_blocks = 0;
    if (mbfWrapper->frameRefCount != -1 && mbfWrapper->frameRefCount != 0)
        in->mbfws.insert(mbfWrapper);
    else
        delete mbfWrapper;
   if (mbfWrapper->frameRefCount != -1 && mbfWrapper->frameRefCount != 0)
      in->mbfws.insert(mbfWrapper);
   else
      delete mbfWrapper;
   return true;
}
float scoring_canny_focus(const PLBG_Block& block)
{
    const int w = block.rectWrapper.rect.width();
    const int h = block.rectWrapper.rect.height();
    if (block.croppedData == nullptr || block.croppedDataSize < w * h)
        return 0.0f;
   const int w = block.rectWrapper.rect.width();
   const int h = block.rectWrapper.rect.height();
   if (block.croppedData == nullptr || block.croppedDataSize < w * h)
      return 0.0f;
    cv::Mat yMat(cv::Size(w, h), CV_8UC1, block.croppedData);
    cv::Mat edges;
   cv::Mat yMat(cv::Size(w, h), CV_8UC1, block.croppedData);
   cv::Mat edges;
   cv::GaussianBlur(yMat, edges, cv::Size(5, 5), 1.5, 1.5);
    //cv::Canny(edges, edges, 50, 100, 3);
   cv::Sobel(yMat, edges, CV_8UC1, 1, 0, 3);
   cv::Canny(edges, edges, 50, 100, 3);
   //cv::Sobel(yMat, edges, CV_8UC1, 1, 0, 3);
   //memcpy(block.croppedData, edges.data, w * h);
    size_t sum = 0;
    std::for_each(edges.begin<uint8_t>(), edges.end<uint8_t>(), [&](uint8_t v)
    {
        sum += (v != 0);
    });
   size_t sum = 0;
   std::for_each(edges.begin<uint8_t>(), edges.end<uint8_t>(), [&](uint8_t v)
   {
      sum += (v != 0);
   });
    float focusRate = (float)sum / (w * h);
    return focusRate;
   float focusRate = (float)sum / (w * h);
   return focusRate;
}
float scoring_histogram_focus(const PLBG_Block& block)
@@ -501,23 +501,23 @@
      {
         iterBlk->mbfWrapper->release();
         iterBlk->release_crop();
            if (iterBlk->rectWrapper.user_data_deleter != nullptr)
                iterBlk->rectWrapper.user_data_deleter(iterBlk->rectWrapper);
        }
         if (iterBlk->rectWrapper.user_data_deleter != nullptr)
            iterBlk->rectWrapper.user_data_deleter(iterBlk->rectWrapper);
      }
   }
   
   in->groupsMature.clear();
   
   for (std::set<MBFrameWrapper*>::iterator iter = in->mbfws.begin(); iter != in->mbfws.end(); )
   {
        MBFrameWrapper* mbfw = *iter;
      MBFrameWrapper* mbfw = *iter;
      if (mbfw->frameRefCount == 0 || mbfw->frameRefCount == -1)
        {
            delete mbfw;
            iter = in->mbfws.erase(iter);
        }
        else
            ++iter;
      {
         delete mbfw;
         iter = in->mbfws.erase(iter);
      }
      else
         ++iter;
   }
   
   in->outputs.clear();
@@ -526,7 +526,7 @@
   for (std::list<PLBG_Group>::iterator iterGrp = in->groups.begin(); iterGrp != in->groups.end(); )
   {
      bool grpMature = false;
        PLBG_Group& currGroup(*iterGrp);
      PLBG_Group& currGroup(*iterGrp);
      if (currGroup.blocks.size() >= in->config.group_size_max)
         grpMature = true;
@@ -539,7 +539,7 @@
         //drop group
         for (std::vector<PLBG_Block>::iterator iterBlk = currGroup.blocks.begin(); iterBlk != currGroup.blocks.end(); ++iterBlk)
         {
                iterBlk->mbfWrapper->release();
            iterBlk->mbfWrapper->release();
            iterBlk->release_crop();
         }
         
@@ -552,16 +552,16 @@
         // generate output group
         in->groupsMature.push_back(currGroup);
         iterGrp = in->groups.erase(iterGrp);
            continue;
         continue;
      }
        ++iterGrp;
      ++iterGrp;
   }
   
   // scoring blocks
   const bool calc_canny = !MH_F_ZEQ(in->config.canny_focus);
    const bool calc_histogram = !MH_F_ZEQ(in->config.histogram_uniformy);
    const bool calc_user_score_1 = !MH_F_ZEQ(in->config.user_score_1_rate);
   const bool calc_histogram = !MH_F_ZEQ(in->config.histogram_uniformy);
   const bool calc_user_score_1 = !MH_F_ZEQ(in->config.user_score_1_rate);
   const float user_score_2_rate = 1.0f - in->config.canny_focus - in->config.histogram_uniformy - in->config.user_score_1_rate;
   const bool calc_user_score_2 = (!MH_F_ZEQ(user_score_2_rate) && in->config.user_score_2_func != nullptr);
   
@@ -576,18 +576,18 @@
         
         if (calc_canny)
         {
            //float cannyScore = scoring_canny_focus(*iterBlk) * 10.0f;
            //totalScore += in->config.canny_focus * cannyScore;
            float cannyScore = scoring_canny_focus(*iterBlk) * 10.0f;
            totalScore += in->config.canny_focus * cannyScore;
         }
         if (calc_histogram)
         {
            float histScore = scoring_histogram_focus(*iterBlk);
            totalScore += in->config.histogram_uniformy * histScore;
         }
            if (calc_user_score_1)
            {
                totalScore += in->config.user_score_1_rate * iterBlk->rectWrapper.user_score_1;
            }
         if (calc_user_score_1)
         {
            totalScore += in->config.user_score_1_rate * iterBlk->rectWrapper.user_score_1;
         }
         if (calc_user_score_2)
         {
            float userScore2 = in->config.user_score_2_func(&(iterBlk->mbfWrapper->frame), iterBlk->rectWrapper.rect, iterBlk->croppedData);
@@ -610,7 +610,7 @@
      output.rectInOriginFrame = iterBestBlk->rectWrapper;
      output.originframe = &(iterBestBlk->mbfWrapper->frame);
      output.score = bestScore;
        output.croppedData = iterBestBlk->croppedData;
      output.croppedData = iterBestBlk->croppedData;
      output.croppedDataSize = iterBestBlk->croppedDataSize;
      in->outputs.push_back(output);