Esempio n. 1
0
  int mpiUser::doImgCalcs(void)
   {

      //
      // we hav these variables on each new image at our disposal
      //

      //public_double_image[0] integrating dark, [1] is the integrating std iamge.
       //num_dark_integrate is how many darks we must integrate total.
         //num_images_to_calc is total images to calc across all ranks
     // img_num_pixels is number if pixels in the iamge.
     //img_size_x, img_size_y is size of iamge in pixels
     // public_short_image are new image, [0] is new iamge

   // my_message is the gui settings, and all mpi iamges. specs from image from detector is there as well.
    //        detector image sopecs also appear at end of piblic_short_image[0], after pidxels. getImageSpecs gets this into
   //  image_specs    - the specs of the image from the detector. also copied into my_message in super class.
    //is_calc_image - if true that means we have an image to calc in this rank.

        printTrace("mpiUser::doImgCalcs================================================");


                //get img specs for public  iamge 0

        if (is_calc_image)
        {
            //get specs for pub img 0
            getImageSpecs(0);


            if (is_print_trace)
            {
                printf("Rank %d got Img num %d\n",rank,image_specs->inpt_img_cnt);
            }

            if (my_message.mpi_save_mem_file && is_calc_image)
            {
                writeImageRaw(public_short_image[0],pub_sh_img_size_bytes*sizeof(short) ,"PubImg",0);
            }


            image_specs->is_descrambled=false;

            //we normally uyse img 0,. if desc is on, we outptu to img 1, so we use that one...



            if (my_message.mpi_is_descramble)
            {
                //take pub image putput to private image
                //partialDescramble(imgx, imgy,0, count,rank,numprocs);

                //we have a bunch of public_image[], all mapped to one contiguous mem
                //starting at public_iamge[0][0]. hwere is the map
                // public_image[0] - raw iamge for all ranks
                // publc_image[1] -descramled image for ll ranks



                image_specs->is_descrambled=true;

                printTrace("doImgCalcs,mpi_b_image_desc2 ");

                if (is_made_desc_table)
                    this->tableDescramble2(1,0);
                else
                {
                    //make desc table and inverse desc table
                    //also desc the image to pub image 1. we will end up desc. again after
                    //making table, so the desc operation here is ONLTY for makin gtable.
                    // desc image is not used.
                    this->descramble_image_jtw1(public_short_image[1],
                                            public_short_image[0],
                                            img_size_x,
                                            img_size_y,
                                            img_num_pixels);

                    //alter desc table to remove overscan lines
                    //!!if (message&mpi_b_remove_overscan)
                    this->removeOverscan(public_short_image[1],
                                             public_short_image[1],
                                             img_size_x,
                                             img_size_y,
                                             img_num_pixels);

                    //we will calc new desc table as we desc image
                    is_made_desc_table=true;

                    //now clear the image and do a table descranble. this is needed if overscan
                    //removal is on, so extra puixels at end of images will be zero.
                    //extra pixels happen becasue we remove overscan pixels, and shift whole image\
                    // to top left corner. so we end up w/ extra pixels on right and bottom.
                    clearImages(1);

                    //now do the actual desc, amd rem overscan
                    this->tableDescramble2(1,0);


                }
                //do this calc
                memcpy(public_short_image[0],public_short_image[1],img_num_pixels*sizeof(short));

            }


            if (my_message.mpi_is_flip_endian)
            {
                flipEndian(0);
            }

            my_message.gui.is_acq_dark_RBV=is_acc_darks;

            if (is_acc_darks)
            {
                //accum pub img 0 into dark accum... of needed.
                // 1st 0 is input imate or puclc_sh_image 0.
                //2nd arg0 is puiblic double image 0.

                accumDarkStd(0,0);


                //
                // now we must make a square image, and accum into the 2nd pub image.
                //

                // make a sqire image
                double dval;
                for (int p=0; p<img_num_pixels;p++)
                {
                    dval =(double) public_short_image[0][p];
                    dval = dval*dval;
                    square_image[p] = dval;
                }

                //accum square intop public_double_iamge[1]
                accumDarkStd(square_image,1);

            }

            if (my_message.mpi_sub_dark && is_calc_image)
            {


                //0 is offset from top of image, 1 is publc_image[1]
                printTrace("doImgCalcs, mpi_b_sub_dark");
                subDark(0);


            }

            image_specs->dark_accum_tot=dark_integrate_counter;
            image_specs->rank_dark_accum_cnt=rank_dark_accum_cnt;

            if (my_message.mpi_is_makeraw_imm )
            {
                printTrace("mpiUser- making raw IMM\n");

                my_imm.rawToIMM(
                        (unsigned char*)public_short_image[0],
                        img_num_pixels*sizeof(short),
                        2,
                        img_size_x,
                        img_size_y,
                        0,
                        0,
                        image_specs->inpt_img_cnt,
                        temp_image,
                        &my_message.imm_bytes);

                    //imm_bytes is img siize plus imm header size
                image_specs->is_raw_imm=true;
                image_specs->is_raw=false;
                image_specs->imm_num_pixels=img_num_pixels;
                image_specs->is_compressed=false;
                image_specs->num_pixels=my_message.imm_bytes/2;

                immHeader *immh = (immHeader*)temp_image;
                immh->systick=image_specs->system_clock;
                immh->elapsed=(double)(immh->systick) / 1000.0;
                immh->corecotick=image_specs->inpt_img_cnt;
                memcpy(public_short_image[0],temp_image,my_message.imm_bytes);
            }

            if (my_message.mpi_is_makecomp_imm )
            {
                printTrace("mpiUser- making comp IMM\n");
                my_imm.rawToCompIMM(
                        (unsigned char*)public_short_image[0],
                        img_num_pixels*sizeof(short),
                        2,
                        img_size_x,
                        img_size_y,
                        0,
                        image_specs->img_len_shorts * 2,//max size of space for data
                        (unsigned char*)temp_image,
                        &my_message.imm_bytes);


                image_specs->is_raw_imm=false;
                image_specs->is_raw=false;
                immHeader *imh = (immHeader*)((unsigned char*)temp_image);
                image_specs->imm_num_pixels=imh->dlen;
                image_specs->is_compressed=true;
                image_specs->num_pixels=my_message.imm_bytes/2;

                immHeader *immh = (immHeader*)temp_image;
                immh->systick=image_specs->system_clock;
                immh->elapsed=(double)(immh->systick) / 1000.0;
                immh->corecotick=image_specs->inpt_img_cnt;


                memcpy(public_short_image[0],temp_image,my_message.imm_bytes);

            }


            if (my_message.gui.which_img_view==1)
            {
                //adrk img
                //std img
                image_specs->is_raw_imm=false;
                image_specs->is_raw=true;

                image_specs->imm_num_pixels=0;
                image_specs->is_compressed=false;
                image_specs->num_pixels=img_num_pixels;


                for (int k=0;k<img_num_pixels;k++)
                {
                    public_short_image[0][k]=(unsigned short)(public_double_image[0][k]);
                }

            }

            if (my_message.gui.which_img_view==2)
            {
                //std img
                image_specs->is_raw_imm=false;
                image_specs->is_raw=true;

                image_specs->imm_num_pixels=0;
                image_specs->is_compressed=false;
                image_specs->num_pixels=img_num_pixels;


                for (int k=0;k<img_num_pixels;k++)
                {
                    public_short_image[0][k]=(unsigned short)(public_double_image[1][k]);
                }

            }

            if (my_message.gui.which_img_view==3)
            {
                //thresh img:

                image_specs->is_raw_imm=false;
                image_specs->is_raw=true;

                image_specs->imm_num_pixels=0;
                image_specs->is_compressed=false;
                image_specs->num_pixels=img_num_pixels;

                memcpy(public_short_image[0],sthresh_image,img_num_pixels*sizeof(short));
            }

            image_specs->processed_by_rank=rank;
    }

        //must be outside of the if_calc_iamge
        // this must execute on every rank regardless if we have img.
        // has barriers and fences etc.

        //we get total average of all darks into pub dooub img 0.
        //is_finish_darks goes true when it is time to compute total sum,
        // that is, when accum is done. we must set to false ourselves.
        if (is_finish_darks)
        {
            combineDarkStd(0,1.0);
            // here we will get basic sum of all squared images into pub doub img 1.
            double noise_mult_factor =1.0;
            combineDarkStd(1,noise_mult_factor);

            //writeImageRaw(public_double_image[0],img_num_pixels*sizeof(double),"AA_DsumImage",0);
            //writeImageRaw(public_double_image[1],img_num_pixels*sizeof(double),"AA_DsumSqImage",0);
            // now calc the std image and thresh hold iamges
            calcThresh();
           // writeImageRaw(public_double_image[0],img_num_pixels*sizeof(double),"AA_DAveImage",0);
            //writeImageRaw(public_double_image[1],img_num_pixels*sizeof(double),"AA_DStdImage",0);

            //writeImageRaw(sdark_image,img_num_pixels*sizeof(short),"AA_UDarkImage",0);
            //writeImageRaw(sthresh_image,img_num_pixels*sizeof(short),"AA_UThreshImage",0);

            //writeImageRaw(square_image,img_num_pixels*sizeof(double),"AA_DVarianceImg",0);

            //is_finish_darks=false;
        }





        printTrace("mpiUser::doImgCalcs_______________________________________________");


return(1);
  }
bool PlayFieldDetectionModule::run()
{
  if(firstTime)
  {
    if(imgARGB32.empty() || imgARGB32.data == NULL)
    {
      this->height = m_data->currentImage->height();
      this->width = m_data->currentImage->width();
      this->imgARGB32 = cv::Mat(height, width, CV_8UC4 );
    }

    if(m_data->fgImage == NULL)
    {
      m_data->fgImage = new QImage(width,height, QImage::Format_Indexed8);
      m_data->fgImage->setColorTable(*(m_data->grayScaleTable));
      memset(m_data->fgImage->bits(), 0, height*m_data->fgImage->bytesPerLine());
    }
    if(m_data->reliabilityMap == NULL || m_data->reliabilityMap->isNull())
    {
      m_data->reliabilityMap = new QImage(width,height, QImage::Format_ARGB32);
    }

    this->reliabilityNormalized = cv::Mat(height,width, CV_8UC1);

    this->nonField = cv::Mat(height, width, CV_8UC1 );
    ptr_nonField = nonField.data;

    QByteArray string8bit = this->fileMaskName.toLocal8Bit();
#ifdef __OPENCV3__
    this->fieldMask = cv::imread(string8bit.data(), cv::IMREAD_GRAYSCALE);
#else
    this->fieldMask = cv::imread(string8bit.data(), CV_LOAD_IMAGE_GRAYSCALE );
#endif
//    if(fieldMask.empty() && !fileMaskName.compare("none"))
    if(fieldMask.empty() )
    {
//      AppendToLog("PlayFieldDetectionModule: Warning: Mask Image "+ this->fileMaskName + " not found.\n");
      this->useMask = false;
    }
    else
    {
      if(fieldMask.rows == height && fieldMask.cols == width)
        this->useMask = true;
      else
      {
        this->useMask = false;
        this->fieldMask = cv::Mat();
        AppendToLog("PlayFieldDetectionModule: Warning: 'Mask Image' doesnt have the needed dimension. Mask Image won't be use.\n");
      }
    }

    criteriaMap = cv::Mat(height, width, CV_8UC3, cv::Scalar(0,255,255));//yellow first criteria

    firstTime = false;
  }

  uchar *ptr_imgData = m_data->currentImage->bits();

  memcpy(imgARGB32.data, ptr_imgData, m_data->currentImage->height()*m_data->currentImage->bytesPerLine());
#ifdef __OPENCV3__
  cv::cvtColor(imgARGB32, currImgC3, cv::COLOR_RGBA2BGR);
  cv::cvtColor(currImgC3, currGrayImg, cv::COLOR_BGR2GRAY );
#else
  cv::cvtColor(imgARGB32, currImgC3, CV_RGBA2BGR);
  cv::cvtColor(currImgC3, currGrayImg, CV_BGR2GRAY );
#endif
  ptr_currGrayImg = currGrayImg.data;

  std::vector<cv::Mat> bgr_planes;
  cv::split( currImgC3, bgr_planes );

  float range[] = { 0, 255} ;
  const float* histRange = { range };

  cv::calcHist( &bgr_planes[0], 1, 0, this->fieldMask, blueHist, 1, &numBins, &histRange, true, false );
  cv::calcHist( &bgr_planes[1], 1, 0, this->fieldMask, greenHist, 1, &numBins, &histRange, true, false );
  cv::calcHist( &bgr_planes[2], 1, 0, this->fieldMask, redHist, 1, &numBins, &histRange, true, false );
  cv::calcHist( &currGrayImg, 1, 0, this->fieldMask, grayHist, 1, &numBins, &histRange, true, false );

//  percentilCut(blueHist, 1.5);
//  percentilCut(greenHist, 1.5);
//  percentilCut(redHist, 1.5);
//  percentilCut(grayHist, 1.5);

  if(this->displayHistogram)
  {
    showHistogram(blueHist, "blueHist");
    showHistogram(greenHist, "greenHist");
    showHistogram(redHist, "redHist");
    showHistogram(grayHist, "grayHist");
  }

  this->blueThreshold = calcThresh(blueHist,&this->bluePeak);
  this->greenThreshold = calcThresh(greenHist,&this->greenPeak);
  this->redThreshold = calcThresh(redHist,&this->redPeak);

  this->grayPeak = getMaxLoc( grayHist);

  float stdGray = 0, grayMean;

  grayMean = cv::mean(currGrayImg)[0];
  for( int i = 0; i < currGrayImg.rows*currGrayImg.cols; i++)
  {
    stdGray += (ptr_currGrayImg[i] - grayMean ) * (ptr_currGrayImg[i] - grayMean );
  }
  stdGray /= currGrayImg.rows*currGrayImg.cols;
  stdGray = sqrt(stdGray);

//  this->grayThreshold = this->grayPeak + this->beta * stdGray;
  this->grayThreshold = this->beta * stdGray;

//hand sets values
//  this->bluePeak = 30;
//  this->greenPeak = 80;
//  this->redPeak = 0;
//  this->grayPeak = 74;

//  this->blueThreshold = 95;
//  this->greenThreshold = 200;
//  this->redThreshold = 90;
//  this->grayThreshold = grayPeak +  this->beta * stdGray;

//  std::cout<<"blue: " <<(int)blueThreshold <<  " "<< (int)bluePeak <<std::endl;
//  std::cout<<"green "<< (int)greenThreshold << " "<< (int)greenPeak<<std::endl;
//  std::cout<<"red " <<(int)redThreshold << " "<< (int)redPeak<<std::endl;
//  std::cout<< "gray" <<(int)grayThreshold << " "<< (int)grayPeak<<std::endl;

  //grass clasification: 0 -> grass; 255-> non-grass
  ptr_blueChannel = bgr_planes[0].data,
      ptr_greenChannel = bgr_planes[1].data,
      ptr_redChannel = bgr_planes[2].data;

  ptr_nonField = nonField.data;
  memset(ptr_nonField, 255, nonField.cols * nonField.rows);

  //foreground classification
  featureMap = bgr_planes[2].clone();
  for(int i = 0; i < width*height; i++)
  {
    if(this->useMask && fieldMask.data[i]  == 0)
    {
      ptr_nonField[i] = 0;
      featureMap.data[i] = 0;
      continue;
    }

     minFeature = ptr_redChannel[i];
     minReliability = normalizeBothSideScale(minFeature, ptr_greenChannel[i]);
    if( ptr_redChannel[i] < ptr_greenChannel[i] ) //criteria
    {
      reliability = normalizeBothSideScale(ptr_blueChannel[i], ptr_greenChannel[i]);
      if(minReliability >  reliability)
      {
        minFeature = ptr_blueChannel[i];
        minReliability = reliability;
      }

      //blue -  green = cian
      criteriaMap.data[3*i] = 255;
      criteriaMap.data[3*i + 1] = 255;
      criteriaMap.data[3*i + 2] = 0;
      if(  ptr_blueChannel[i] < ptr_greenChannel[i]) //criteria
      {
        threshold = greenPeak + greenThreshold;
        reliability = normalizeBothSideScale(ptr_greenChannel[i], threshold > 255? 255: threshold);
        if(minReliability >  reliability)
        {
            minFeature = ptr_greenChannel[i];
            minReliability = reliability;
        }

        //green
        criteriaMap.data[3*i] = 0;
        criteriaMap.data[3*i + 1] = 255;
        criteriaMap.data[3*i + 2] = 0;
        if( abs( ptr_greenChannel[i] - greenPeak ) <= greenThreshold) //criteria
        {
          threshold = bluePeak + blueThreshold;
          reliability = normalizeBothSideScale(ptr_blueChannel[i], threshold > 255? 255: threshold);
          if(minReliability >  reliability)
          {
            minFeature = ptr_blueChannel[i];
            minReliability = reliability;
          }

          //blue
          criteriaMap.data[3*i] = 255;
          criteriaMap.data[3*i + 1] = 0;
          criteriaMap.data[3*i + 2] = 0;
          if( abs( ptr_blueChannel[i] - bluePeak ) <= blueThreshold) //criteria
          {

            threshold = redPeak + redThreshold;
            reliability = normalizeBothSideScale(ptr_redChannel[i], threshold > 255? 255: threshold);
            if(minReliability >  reliability)
            {
              minFeature = ptr_redChannel[i];
              minReliability = reliability;
            }

            //red
            criteriaMap.data[3*i] = 0;
            criteriaMap.data[3*i + 1] = 0;
            criteriaMap.data[3*i + 2] = 255;
            if( abs( ptr_redChannel[i] - redPeak ) <= redThreshold) //criteria
            {

              threshold = grayPeak + grayThreshold;
              reliability = normalizeBothSideScale(ptr_currGrayImg[i], threshold > 255? 255: threshold);
              if(minReliability >  reliability)
              {
                minFeature = ptr_currGrayImg[i];
                minReliability = reliability;
              }

              //gray
              criteriaMap.data[3*i] = 127;
              criteriaMap.data[3*i + 1] = 127;
              criteriaMap.data[3*i + 2] = 127;
              if( abs(ptr_currGrayImg[i] - grayPeak) <= grayThreshold) //criteria
              {
                //gray
                criteriaMap.data[3*i] = 255;
                criteriaMap.data[3*i + 1] = 255;
                criteriaMap.data[3*i + 2] = 255;

                ptr_nonField[i] = 0;
              }
            }
          }
        }
      }
    }

    //linear scale
    this->featureMap.data[i] = this->minFeature;
    this->reliabilityNormalized.data[i] = this->minReliability;

  }

  //adaptative threshold, only for experimentation
//  cv::Mat binary;
//  cv::adaptiveThreshold(reliabilityNormalized, binary, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 21, 13);
//  cv::threshold(reliabilityNormalized, binary, 125, 255, cv::THRESH_OTSU);
//  binary = binary == 0;
//  binary = binary & fieldMask;
//  cv::namedWindow("segmentation");
//  cv::imshow("segmentation",binary);

  if(displayFeatureMap)
  {
    cv::Mat featureMapThermal = ThermalColor::reliabilityToThermal(featureMap);
#ifdef __OPENCV3__
    cv::cvtColor(featureMapThermal,featureMapThermal, cv::COLOR_BGR2RGB);
#else
    cv::cvtColor(featureMapThermal,featureMapThermal, CV_BGR2RGB);
#endif
    //    cv::namedWindow("featureMap");
//    cv::imshow("featureMap", featureMap); //grayscale
    cv::namedWindow("featureMapThermal");
    cv::imshow("featureMapThermal", featureMapThermal);

  }
  if(displayCriteriaMap)
  {
    cv::namedWindow("Criteria");
    cv::imshow("Criteria",criteriaMap);
  }

  //copy back foreground
  memcpy(m_data->fgImage->bits(), nonField.data, height*m_data->fgImage->bytesPerLine());

  //copy back reliability
//  cv::namedWindow("reliability");
//  cv::imshow("reliability",reliabilityNormalized); //grayScale
  reliabilityNormalizedThermal = ThermalColor::reliabilityToThermal(reliabilityNormalized);
#ifdef __OPENCV3__
  cv::cvtColor(reliabilityNormalizedThermal, imgARGB32, cv::COLOR_BGR2RGBA);
#else
  cv::cvtColor(reliabilityNormalizedThermal, imgARGB32, CV_BGR2RGBA);
#endif
  memcpy(m_data->reliabilityMap->bits(), imgARGB32.data, height * m_data->reliabilityMap->bytesPerLine());

  return true;
}