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; }