cv::Mat getSyntheticImage(const Mat& image) { int rand_type = rand(); Mat result = image.clone(); if (rand_type % 2 == 0) { int ran_x = rand() % 5 - 2; int ran_y = rand() % 5 - 2; result = translateImg(result, ran_x, ran_y); } else if (rand_type % 2 != 0) { float angle = float(rand() % 15 - 7); result = rotateImg(result, angle); } return result; }
bool SpatialAverageSpotter::train(string dirPath) { int count=0; vector<vector<tuple<int,Point2f> > > features; featureAverages.resize(codebook->size()); for (int i =0; i<codebook->size(); i++) featureAverages[i]=Mat(BASE_SIZE,BASE_SIZE,CV_32F,Scalar(0)); DIR *dir; struct dirent *ent; if ((dir = opendir (dirPath.c_str())) != NULL) { /* print all the files and directories within directory */ // Mat img; while ((ent = readdir (dir)) != NULL) { string fileName(ent->d_name); // cout << "examining " << fileName << endl; if (fileName[0] == '.' || fileName[fileName.size()-1]!='G') continue; Mat img = imread(dirPath+fileName, CV_LOAD_IMAGE_GRAYSCALE); // resize(img,img,Size(0,0),2,2); threshold(img,img,120.0,255,THRESH_BINARY); // windowWidth += img.cols; // windowHeight += img.rows; // int avg=0; // for (int x=0; x<img.cols; x++) // for (int y=0; y<img.rows; y++) // avg += (int)img.at<unsigned char>(y,x); //// cout << "avg="<<avg<<"/"<<img.cols*img.rows<<" = "<<avg/(img.cols*img.rows)<<endl; // avg /= img.cols*img.rows; resize(img,img,Size(PRE_BASE_SIZE,PRE_BASE_SIZE*((0.0+img.rows)/img.cols))); copyMakeBorder( img, img, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_CONSTANT, 255 ); assert(img.cols > 1 && img.rows > 1); adjustedTrainingImages.push_back(img.clone()); Point2f centerOfMass = findCenterOfMass(img); int offsetx=(img.cols/2)-centerOfMass.x; int offsety=(img.rows/2)-centerOfMass.y; translateImg(img,offsetx,offsety); vector<KeyPoint> keypoints; Mat desc; detectKeypoints( img,keypoints, desc); Mat out; cvtColor(img,out,CV_GRAY2RGB); circle(out,centerOfMass,1,Scalar(0,0,255)); features.resize(count+1); //double scaling = BASE_SIZE/img for (int r=0; r<desc.rows; r++) { int f = codebook->quantize(desc.row(r)); Point2f offsetPoint(keypoints[r].pt.x - centerOfMass.x, keypoints[r].pt.y - centerOfMass.y); features[count].push_back(make_tuple(f,offsetPoint));//we're ignoring the keypoint scale.. // circle(out,keypoints[r].pt,keypoints[r].size,Scalar(colorTable[f])); Rect rec(keypoints[r].pt.x-(keypoints[r].size/2),keypoints[r].pt.y-(keypoints[r].size/2),keypoints[r].size,keypoints[r].size); rectangle(out,rec,Scalar(colorTable[f])); } guassColorIn(features[count]); imshow("learning keypoints",out); cout << "image "<<count<<endl; waitKey(5); count++; // img.release(); } closedir (dir); } else { /* could not open directory */ perror (""); return false; } //We now step through adjusting the scales of the various images so the guass coloring is maximized //But we may still want to look at tfidf to see which ones should be weighted more, etc. maximizeAlignment(features); float max=0; float min =99999; float avg_max=0; int firstx=9999; int lastx=0; int firsty=9999; int lasty=0; for (int f=0; f<codebook->size(); f++) { float local_max=0; bool hitFirst=false; for (int x=0; x<featureAverages[f].cols; x++) for (int y=0; y<featureAverages[f].rows; y++) { float val = featureAverages[f].at<float>(y,x); if (val > 300 || val < -300) cout << "val (" << x <<","<<y<<") " << val << endl; if (val>max) max=val; if (val<min) min=val; if (val>local_max) local_max=val; if (val>WINDOW_THRESH) { if (!hitFirst) { hitFirst=true; if (x<firstx) firstx=x; if (y<firsty) firsty=y; } if (x>lastx) lastx=x; if (y>lasty) lasty=y; } } avg_max+=local_max; } // penalty=min+(max-min)*.2; avg_max /= codebook->size(); penalty=avg_max*.15;//.2 // windowWidth/=count; // windowHeight/=count; windowWidth = lastx-firstx; windowHeight = lasty-firsty; cout << "window size is "<<windowWidth<<"x"<<windowHeight<<endl; //show averages showAverages(); return true; }
void SpatialAverageSpotter::maximizeAlignment(vector<vector<tuple<int,Point2f> > > &features) { int stayCount=0; int iters=0; vector<bool> adjusted(features.size(),false); while (stayCount<STAY_THRESH*features.size() && iters<MAX_REF_ITER*features.size())//20 { iters++; int imageNum= rand()%features.size(); int imageNumOld=imageNum; while(1) { if (!adjusted[imageNum]) { adjusted[imageNum]=true; break; } imageNum = (imageNum+1)%features.size(); if ((imageNum) == imageNumOld) { adjusted.assign(features.size(),false); adjusted[imageNum]=true; // stayCount /= 2; stayCount=0; break; } } double shiftStep = 2*(1.0-iters/(0.0+MAX_REF_ITER*features.size()));//3* DD 2* TT if (shiftStep<1) shiftStep=1.0; //1.0 DD double scaleStep = .03*(1.0-iters/(0.0+MAX_REF_ITER*features.size()));//.01 DD double scaleStep2 = .06*(1.0-iters/(0.0+MAX_REF_ITER*features.size()));// .015 DD if (scaleStep<1) scaleStep=.003; //DD remove if (scaleStep2<1) scaleStep2=.006; //DD remove //examine gradient at each f point (discluding self) //if gradients agrre, make scale step guassColorOut(features[imageNum]); double bestScore=0; ExemplarTransform bestMove=STAY; double leftScore=0; double rightScore=0; double upScore=0; double downScore=0; double smallerScore=0; double biggerScore=0; double shortenScore=0; double hightenScore=0; double slimScore=0; double fattenScore=0; // double leftSmallerScore=0; // double rightSmallerScore=0; // double upSmallerScore=0; // double downSmallerScore=0; // double leftBiggerScore=0; // double rightBiggerScore=0; // double upBiggerScore=0; // double downBiggerScore=0; for (tuple<int,Point2f> f : features[imageNum]) { bestScore += getUsingOffset(featureAverages[get<0>(f)],get<1>(f).x,get<1>(f).y); leftScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x-shiftStep, get<1>(f).y); rightScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x+shiftStep, get<1>(f).y); upScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x, get<1>(f).y-shiftStep); downScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x, get<1>(f).y+shiftStep); smallerScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x*(1-scaleStep), get<1>(f).y*(1-scaleStep)); biggerScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x*(1+scaleStep), get<1>(f).y*(1+scaleStep)); shortenScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x,get<1>(f).y*(1-scaleStep2)); hightenScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x, get<1>(f).y*(1+scaleStep2)); slimScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x*(1-scaleStep2), get<1>(f).y); fattenScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x*(1+scaleStep2), get<1>(f).y); // leftSmallerScore += getUsingOffset(featureAverages[get<0>(f)], (get<1>(f).x-shiftStep)*(1-scaleStep), get<1>(f).y*(1-scaleStep)); // rightSmallerScore += getUsingOffset(featureAverages[get<0>(f)], (get<1>(f).x+shiftStep)*(1-scaleStep), get<1>(f).y*(1-scaleStep)); // upSmallerScore += getUsingOffset(featureAverages[get<0>(f)], (get<1>(f).x)*(1-scaleStep), (get<1>(f).y-shiftStep)*(1-scaleStep)); // downSmallerScore += getUsingOffset(featureAverages[get<0>(f)], (get<1>(f).x)*(1-scaleStep), (get<1>(f).y+shiftStep)*(1-scaleStep)); // leftBiggerScore += getUsingOffset(featureAverages[get<0>(f)], (get<1>(f).x-shiftStep)*(1+scaleStep), get<1>(f).y*(1+scaleStep)); // rightBiggerScore += getUsingOffset(featureAverages[get<0>(f)], (get<1>(f).x+shiftStep)*(1+scaleStep), get<1>(f).y*(1+scaleStep)); // upBiggerScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x*(1+scaleStep), (get<1>(f).y-shiftStep)*(1+scaleStep)); // downBiggerScore += getUsingOffset(featureAverages[get<0>(f)], get<1>(f).x*(1+scaleStep), (get<1>(f).y+shiftStep)*(1+scaleStep)); } double test=bestScore; if (leftScore > bestScore) { bestScore=leftScore; bestMove = LEFT; } if (rightScore > bestScore) { bestScore=rightScore; bestMove = RIGHT; } if (upScore > bestScore) { bestScore=upScore; bestMove = UP; } if (downScore > bestScore) { bestScore=downScore; bestMove = DOWN; } if (smallerScore > bestScore) { bestScore=smallerScore; bestMove = SHRINK; } if (biggerScore > bestScore) { bestScore=biggerScore; bestMove = GROW; } if (shortenScore > bestScore) { bestScore=shortenScore; bestMove = SHORTEN; } if (hightenScore > bestScore) { bestScore=hightenScore; bestMove = HIGHTEN; } if (slimScore > bestScore) { bestScore=slimScore; bestMove = SLIM; } if (fattenScore > bestScore) { bestScore=fattenScore; bestMove = FATTEN; } // if (leftSmallerScore > bestScore) // { // bestScore=leftSmallerScore; bestMove = LEFT_SHRINK; // } // if (rightSmallerScore > bestScore) // { // bestScore=rightSmallerScore; bestMove = RIGHT_SHRINK; // } // if (upSmallerScore > bestScore) // { // bestScore=upSmallerScore; bestMove = UP_SHRINK; // } // if (downSmallerScore > bestScore) // { // bestScore=downSmallerScore; bestMove = DOWN_SHRINK; // } // if (leftBiggerScore > bestScore) // { // bestScore=leftBiggerScore; bestMove = LEFT_GROW; // } // if (rightBiggerScore > bestScore) // { // bestScore=rightBiggerScore; bestMove = RIGHT_GROW; // } // if (upBiggerScore > bestScore) // { // bestScore=upBiggerScore; bestMove = UP_GROW; // } // if (downBiggerScore > bestScore) // { // bestScore=downBiggerScore; bestMove = DOWN_GROW; // } auto fI = features[imageNum].begin(); for(; fI!=features[imageNum].end(); fI++) { switch(bestMove) { case LEFT: get<1>(*fI) = Point2f(get<1>(*fI).x-shiftStep, get<1>(*fI).y); break; case RIGHT: get<1>(*fI) = Point2f(get<1>(*fI).x+shiftStep, get<1>(*fI).y); break; case UP: get<1>(*fI) = Point2f(get<1>(*fI).x, get<1>(*fI).y-shiftStep); // cout << "upscore:"<<upScore<<" stayscore:"<<test<<endl; break; case DOWN: get<1>(*fI) = Point2f(get<1>(*fI).x, get<1>(*fI).y+shiftStep); break; case SHRINK: get<1>(*fI) = Point2f(get<1>(*fI).x*(1-scaleStep), get<1>(*fI).y*(1-scaleStep)); break; case GROW: get<1>(*fI) = Point2f(get<1>(*fI).x*(1+scaleStep), get<1>(*fI).y*(1+scaleStep)); break; case SHORTEN: get<1>(*fI) = Point2f(get<1>(*fI).x, get<1>(*fI).y*(1-scaleStep2)); break; case HIGHTEN: get<1>(*fI) = Point2f(get<1>(*fI).x, get<1>(*fI).y*(1+scaleStep2)); break; case SLIM: get<1>(*fI) = Point2f(get<1>(*fI).x*(1-scaleStep2), get<1>(*fI).y); break; case FATTEN: get<1>(*fI) = Point2f(get<1>(*fI).x*(1+scaleStep2), get<1>(*fI).y); break; // case LEFT_SHRINK: // get<1>(*fI) = Point2f((get<1>(*fI).x-shiftStep)*(1-scaleStep), get<1>(*fI).y*(1-scaleStep)); // break; // case RIGHT_SHRINK: // get<1>(*fI) = Point2f((get<1>(*fI).x+shiftStep)*(1-scaleStep), get<1>(*fI).y*(1-scaleStep)); // break; // case UP_SHRINK: // get<1>(*fI) = Point2f((get<1>(*fI).x)*(1-scaleStep), (get<1>(*fI).y-shiftStep)*(1-scaleStep)); // break; // case DOWN_SHRINK: // get<1>(*fI) = Point2f((get<1>(*fI).x)*(1-scaleStep), (get<1>(*fI).y+shiftStep)*(1-scaleStep)); // break; // case LEFT_GROW: // get<1>(*fI) = Point2f((get<1>(*fI).x-shiftStep)*(1+scaleStep), get<1>(*fI).y*(1+scaleStep)); // break; // case RIGHT_GROW: // get<1>(*fI) = Point2f((get<1>(*fI).x+shiftStep)*(1+scaleStep), get<1>(*fI).y*(1+scaleStep)); // break; // case UP_GROW: // get<1>(*fI) = Point2f(get<1>(*fI).x*(1+scaleStep), (get<1>(*fI).y-shiftStep)*(1+scaleStep)); // break; // case DOWN_GROW: // get<1>(*fI) = Point2f(get<1>(*fI).x*(1+scaleStep), (get<1>(*fI).y+shiftStep)*(1+scaleStep)); // break; case STAY: break; } } if(bestMove == STAY) { stayCount+=1; } else if (stayCount>0) { stayCount--; } ////// switch(bestMove) { case LEFT: translateImg(adjustedTrainingImages[imageNum],-shiftStep,0); break; case RIGHT: translateImg(adjustedTrainingImages[imageNum],shiftStep,0); break; case UP: translateImg(adjustedTrainingImages[imageNum],0,-shiftStep); break; case DOWN: translateImg(adjustedTrainingImages[imageNum],0,shiftStep); break; case SHRINK: strechImg(adjustedTrainingImages[imageNum],(1-scaleStep),(1-scaleStep)); break; case GROW: strechImg(adjustedTrainingImages[imageNum],(1+scaleStep),(1+scaleStep)); break; case SHORTEN: strechImg(adjustedTrainingImages[imageNum],1,(1-scaleStep2)); break; case HIGHTEN: strechImg(adjustedTrainingImages[imageNum],1,(1+scaleStep2)); break; case SLIM: strechImg(adjustedTrainingImages[imageNum],(1-scaleStep2),1); break; case FATTEN: strechImg(adjustedTrainingImages[imageNum],(1+scaleStep2),1); break; case STAY: break; } ////// guassColorIn(features[imageNum]); cout <<"image "<<imageNum<<" move "<<bestMove<<", staycount="<<stayCount<<endl; showAverages(); Mat averageImage(adjustedTrainingImages[0].rows,adjustedTrainingImages[0].cols,CV_8U); for (int x=0; x< averageImage.cols; x++) for (int y=0; y<averageImage.rows; y++) { int sum=0; for (Mat image : adjustedTrainingImages) { sum += image.at<unsigned char>(y,x); } sum /= adjustedTrainingImages.size(); assert(sum>=0 && sum<256); averageImage.at<unsigned char>(y,x) = sum; } imshow("average",averageImage); waitKey(5); // imshow("adjusted",adjustedTrainingImages[imageNum]); // waitKey(); } Mat averageImage(adjustedTrainingImages[0].rows,adjustedTrainingImages[0].cols,CV_8U); for (int x=0; x< averageImage.cols; x++) for (int y=0; y<averageImage.rows; y++) { int sum=0; for (Mat image : adjustedTrainingImages) { sum += image.at<unsigned char>(y,x); } sum /= adjustedTrainingImages.size(); assert(sum>=0 && sum<256); averageImage.at<unsigned char>(y,x) = sum; } int i=0; for (Mat image : adjustedTrainingImages) { imshow("adjusted",image); cout << "image "<<i++<<endl; waitKey(5); } imshow("average",averageImage); waitKey(5); }