|
|
|
@ -67,7 +67,9 @@ class PointBase {
|
|
|
|
|
//cout << "x: " << coords["depthPos"]["x"].asDouble() << std::endl;
|
|
|
|
|
//cout << "y: " << coords["depthPos"]["y"].asDouble() << std::endl;
|
|
|
|
|
Point2d newPoint = Point2d(coords["depthPos"]["x"].asDouble() , coords["depthPos"]["y"].asDouble());
|
|
|
|
|
newPoint.x = fmod(newPoint.x,360.0) ;
|
|
|
|
|
pathMap[newPoint] = filePath;
|
|
|
|
|
|
|
|
|
|
points.push_back(newPoint);
|
|
|
|
|
|
|
|
|
|
imgWidthDeg = coords["rectangle"]["w"].asDouble();
|
|
|
|
@ -166,13 +168,13 @@ class PointBase {
|
|
|
|
|
double xDifference = inputPoint.x - points[i].x;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
if(abs(yDifference)<15 && (xDifference<45) && (xDifference>0))
|
|
|
|
|
{
|
|
|
|
|
resultVector.push_back(points[i]);
|
|
|
|
|
toDoVector.push_back(points[i]);
|
|
|
|
|
points.erase(points.begin()+i);
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -182,6 +184,7 @@ class PointBase {
|
|
|
|
|
resultVector.push_back(points[i]);
|
|
|
|
|
toDoVector.push_back(points[i]);
|
|
|
|
|
points.erase(points.begin()+i);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -191,7 +194,7 @@ class PointBase {
|
|
|
|
|
resultVector.push_back(points[i]);
|
|
|
|
|
toDoVector.push_back(points[i]);
|
|
|
|
|
points.erase(points.begin()+i);
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -201,7 +204,16 @@ class PointBase {
|
|
|
|
|
resultVector.push_back(points[i]);
|
|
|
|
|
toDoVector.push_back(points[i]);
|
|
|
|
|
points.erase(points.begin()+i);
|
|
|
|
|
continue;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(abs(yDifference)<0.9*imgHeightDeg && abs(xDifference)<0.8*imgWidthDeg)
|
|
|
|
|
{
|
|
|
|
|
resultVector.push_back(points[i]);
|
|
|
|
|
toDoVector.push_back(points[i]);
|
|
|
|
|
points.erase(points.begin()+i);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return resultVector;
|
|
|
|
@ -381,10 +393,19 @@ class PointBase {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cumdump(int imgWidth,int imgHeight)
|
|
|
|
|
void cumdump(int imgW,int imgH)
|
|
|
|
|
{ //sift takes too long if images are large, so we shrink them
|
|
|
|
|
int imgWidth = imgW;
|
|
|
|
|
int imgHeight = imgH;
|
|
|
|
|
if (imgWidth > 1000)
|
|
|
|
|
{
|
|
|
|
|
imgWidth = int(0.4*imgWidth);
|
|
|
|
|
imgHeight = int(0.4*imgHeight);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int placeCounter =0;
|
|
|
|
|
int roiCounter = 0;
|
|
|
|
|
int tempMatchCounter =0;
|
|
|
|
|
|
|
|
|
|
std::vector <double> edges;
|
|
|
|
|
edges = getEdgeValues();
|
|
|
|
@ -393,10 +414,10 @@ class PointBase {
|
|
|
|
|
double minY=edges[2];
|
|
|
|
|
double maxY=edges[3];
|
|
|
|
|
|
|
|
|
|
int windowHeight = (int)(maxY*(imgHeight/imgHeightDeg))+imgHeight;
|
|
|
|
|
int windowHeight = (int)(maxY*(imgHeight/imgHeightDeg))+imgHeight*2;
|
|
|
|
|
int windowWidth = (int)((360/imgWidthDeg)*imgWidth) + imgWidth;
|
|
|
|
|
|
|
|
|
|
Mat img = Mat::zeros(windowHeight,windowWidth,CV_8UC3);
|
|
|
|
|
Mat img = Mat::zeros(windowHeight,windowWidth,CV_8UC1);
|
|
|
|
|
rectangle(img,Point(3,3),Point(15,15),Scalar(128,128, 0),2,2,0);
|
|
|
|
|
|
|
|
|
|
int imgIdx = 0;
|
|
|
|
@ -494,7 +515,13 @@ class PointBase {
|
|
|
|
|
pngPath = pngPath + "png";
|
|
|
|
|
cout << "file: " << pngPath << std::endl;
|
|
|
|
|
|
|
|
|
|
Mat imgSmall = imread(pngPath,IMREAD_COLOR);
|
|
|
|
|
Mat imgSmall = imread(pngPath,IMREAD_GRAYSCALE);
|
|
|
|
|
//resizing
|
|
|
|
|
cout << "w:" <<imgWidth << " h: " <<imgHeight <<"\n";
|
|
|
|
|
resize(imgSmall, imgSmall, Size(imgWidth, imgHeight), INTER_LINEAR);
|
|
|
|
|
|
|
|
|
|
Ptr<CLAHE> clahe = cv::createCLAHE(4.0, cv::Size(8,8));
|
|
|
|
|
clahe->apply(imgSmall,imgSmall);
|
|
|
|
|
cout<< cv::typeToString( imgSmall.type() );
|
|
|
|
|
|
|
|
|
|
cout <<minX <<"\n";
|
|
|
|
@ -505,7 +532,14 @@ class PointBase {
|
|
|
|
|
cout << (int)round(coords.y)*(int)(imgHeight/imgHeightDeg)<< "\n";
|
|
|
|
|
|
|
|
|
|
//first image is added to result img, others will be stitched
|
|
|
|
|
if (qIdx==0) imgSmall.copyTo(img(cv::Rect((int)round(coords.x)*(int)(imgWidth/imgWidthDeg),(int)round(coords.y)*(int)(imgHeight/imgHeightDeg),imgSmall.cols, imgSmall.rows)));
|
|
|
|
|
|
|
|
|
|
if (qIdx==0)
|
|
|
|
|
{ cout << "AM TRYING TO PLACE TO \n \n";
|
|
|
|
|
cout << "imgHeightDeg" << imgHeightDeg <<"\n";
|
|
|
|
|
placeCounter++;
|
|
|
|
|
cout << "X: " << (int)round(coords.x)*(int)(imgWidth/imgWidthDeg) << " Y:" << (int)round(coords.y)*(int)(imgHeight/imgHeightDeg) << " W: " <<imgSmall.cols << " H: " << imgSmall.rows << "\n";
|
|
|
|
|
imgSmall.copyTo(img(cv::Rect((int)round(coords.x)*(int)(imgWidth/imgWidthDeg),(int)round(coords.y)*(int)(imgHeight/imgHeightDeg),imgSmall.cols, imgSmall.rows)));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
//default ROI location and size
|
|
|
|
|
int xLoc=(int)round(coords.x)*(int)(imgWidth/imgWidthDeg) - imgWidth; //=normalized x-coord. minus 1 width of image
|
|
|
|
@ -520,6 +554,7 @@ class PointBase {
|
|
|
|
|
if (yLoc + yHeight > windowHeight) yHeight = windowHeight - yLoc;
|
|
|
|
|
|
|
|
|
|
//create the ROI
|
|
|
|
|
cout << "AM DOING ROI \n \n";
|
|
|
|
|
Mat roi;
|
|
|
|
|
roi = img(Rect(xLoc, yLoc, xWitdth, yHeight));
|
|
|
|
|
/*imshow("roi",roi);
|
|
|
|
@ -561,7 +596,7 @@ class PointBase {
|
|
|
|
|
drawMatches(roi,keypointsROI,imgSmall,keypointsImg,matches,imageMatches);
|
|
|
|
|
cv::namedWindow("matches");
|
|
|
|
|
cv::imshow("matches",imageMatches);
|
|
|
|
|
cv::waitKey(0);
|
|
|
|
|
//cv::waitKey(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -596,7 +631,9 @@ class PointBase {
|
|
|
|
|
cout<<"TU BY MALI BYT MATCHE " <<'\n';
|
|
|
|
|
std::vector< DMatch > good_matches;
|
|
|
|
|
//float ratio = 0.4; // As in Lowe's paper; can be tuned
|
|
|
|
|
for (float ratio = 0.4; good_matches.size()<2; ratio+=0.05)
|
|
|
|
|
/*
|
|
|
|
|
//this is continous worsening of the ratio in order to get good matches - after 0.4 the results were getting kinda bad tho
|
|
|
|
|
for (float ratio = 0.4; good_matches.size()<3; ratio+=0.05)
|
|
|
|
|
{
|
|
|
|
|
good_matches.clear();
|
|
|
|
|
cout << "RATIO: " <<ratio <<"\n";
|
|
|
|
@ -607,15 +644,20 @@ class PointBase {
|
|
|
|
|
{
|
|
|
|
|
good_matches.push_back(matches[i][0]);
|
|
|
|
|
cout<<"GOOD MATCH DISTANCE " << matches[i][0].distance <<'\n';
|
|
|
|
|
}/*
|
|
|
|
|
else{
|
|
|
|
|
cout<< "BAD MATCH \n";
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
float ratio =0.4;
|
|
|
|
|
for (int i = 0; i < matches.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//if there are no good matches, try adaptive thresholding
|
|
|
|
|
|
|
|
|
|
if (matches[i][0].distance < ratio * matches[i][1].distance)
|
|
|
|
|
{
|
|
|
|
|
good_matches.push_back(matches[i][0]);
|
|
|
|
|
cout<<"GOOD MATCH DISTANCE " << matches[i][0].distance <<'\n';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -634,8 +676,81 @@ class PointBase {
|
|
|
|
|
//find a transformation based on good matches
|
|
|
|
|
//we do not need a Homography, since we deal with affine transformations (no viewport transf. are expected)
|
|
|
|
|
//Mat H = findHomography( Mat(obj), Mat(scene), RANSAC );
|
|
|
|
|
Mat H = estimateAffinePartial2D( Mat(obj), Mat(scene), noArray(),RANSAC );
|
|
|
|
|
Mat H;
|
|
|
|
|
if(good_matches.size()>=3) H = estimateAffinePartial2D( Mat(obj), Mat(scene), noArray(),RANSAC );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//here we check for errors - either there were not enough good matches, OR an affine transformation could not be estimated
|
|
|
|
|
//we use template matching if errors occured
|
|
|
|
|
if(good_matches.size()<3 || H.empty())
|
|
|
|
|
{
|
|
|
|
|
tempMatchCounter++;
|
|
|
|
|
Mat workRoi, workImg;
|
|
|
|
|
workRoi = roi.clone();
|
|
|
|
|
workImg = imgSmall.clone();
|
|
|
|
|
|
|
|
|
|
GaussianBlur(roi, workRoi, Size(3, 3), 0);
|
|
|
|
|
GaussianBlur(imgSmall, workImg, Size(3, 3), 0);
|
|
|
|
|
|
|
|
|
|
Canny(workRoi, workRoi, 100, 200, 3, false);
|
|
|
|
|
Canny(workImg, workImg, 100, 200, 3, false);
|
|
|
|
|
|
|
|
|
|
Mat result;
|
|
|
|
|
double min_val, max_val;
|
|
|
|
|
Point min_loc, max_loc;
|
|
|
|
|
matchTemplate(workRoi,workImg,result,TM_CCOEFF);
|
|
|
|
|
minMaxLoc(result,&min_val,&max_val,&min_loc,&max_loc);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mat roiMask, roiDT, imgWarpedMask,imgDT,roiMaskFinal,imgMaskFinal,imgNew;
|
|
|
|
|
threshold(roi,roiMask,1,255,CV_8U);
|
|
|
|
|
imgWarpedMask = Mat::zeros(roi.rows,roi.cols,CV_8U);
|
|
|
|
|
imgWarpedMask(Rect(max_loc.x,max_loc.y,imgSmall.cols,imgSmall.rows))=1.0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
distanceTransform(roiMask,roiDT,DIST_L2, 3);
|
|
|
|
|
distanceTransform(imgWarpedMask,imgDT,DIST_L2, 3);
|
|
|
|
|
normalize(roiDT, roiDT, 0.0, 1.0, NORM_MINMAX);
|
|
|
|
|
normalize(imgDT, imgDT, 0.0, 1.0, NORM_MINMAX);
|
|
|
|
|
|
|
|
|
|
cv::divide(roiDT,(roiDT+imgDT),roiMaskFinal);
|
|
|
|
|
cv::divide(imgDT,(roiDT+imgDT),imgMaskFinal);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
normalize(roiMaskFinal, roiMaskFinal, 0.0, 255.0, NORM_MINMAX);
|
|
|
|
|
normalize(imgMaskFinal, imgMaskFinal, 0.0, 255.0, NORM_MINMAX);
|
|
|
|
|
imgNew = Mat::zeros(roi.rows,roi.cols,CV_8U);
|
|
|
|
|
imgSmall.copyTo(imgNew(Rect(max_loc.x , max_loc.y , imgSmall.cols,imgSmall.rows)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
roiMaskFinal.convertTo(roiMaskFinal,CV_8UC1);
|
|
|
|
|
imgMaskFinal.convertTo(imgMaskFinal,CV_8UC1);
|
|
|
|
|
roi.convertTo(roi,CV_32FC1);
|
|
|
|
|
imgNew.convertTo(imgNew,CV_32FC1);
|
|
|
|
|
roiMaskFinal.convertTo(roiMaskFinal,CV_32FC1);
|
|
|
|
|
imgMaskFinal.convertTo(imgMaskFinal,CV_32FC1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
multiply(roiMaskFinal,roi,roi);
|
|
|
|
|
cout<<cv::typeToString(imgMaskFinal.type())<< "imgMaskFinal TYPE \n";
|
|
|
|
|
cout<<cv::typeToString(imgNew.type())<< "imgNew TYPE \n";
|
|
|
|
|
|
|
|
|
|
multiply(imgMaskFinal,imgNew,imgNew);
|
|
|
|
|
|
|
|
|
|
cv::add(roi,imgNew, roi);
|
|
|
|
|
normalize(roi, roi, 0.0, 255.0, NORM_MINMAX);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//imgSmall.copyTo(roi(Rect(max_loc.x , max_loc.y , imgSmall.cols,imgSmall.rows)));
|
|
|
|
|
|
|
|
|
|
roi.copyTo(img(Rect(xLoc, yLoc, xWitdth, yHeight)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
roiCounter++;
|
|
|
|
|
cv::Mat resultWarp;
|
|
|
|
|
cv::Mat resultBlend,roiMask,imgWarpedMask,overlapMask,overlapDST,roiDT, imgDT;
|
|
|
|
|
//warpPerspective(imgSmall,roi,H,cv::Size(roi.cols,roi.rows));
|
|
|
|
@ -645,7 +760,7 @@ class PointBase {
|
|
|
|
|
imshow("imgSmall", imgSmall);
|
|
|
|
|
imshow( "resultWarp", resultWarp );
|
|
|
|
|
imshow("roi", roi);
|
|
|
|
|
cv::waitKey(0);
|
|
|
|
|
//cv::waitKey(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//cv::addWeighted( roi, 0.5, resultWarp, 0.5, 0.0, resultBlend);
|
|
|
|
@ -654,13 +769,14 @@ class PointBase {
|
|
|
|
|
threshold(roi,roiMask,1,255,CV_8U);
|
|
|
|
|
threshold(resultWarp,imgWarpedMask,1,255,CV_8U);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
multiply(roiMask,imgWarpedMask,overlapMask);
|
|
|
|
|
//we need to change type in order for img multiplication to work in OpenCV
|
|
|
|
|
cv::cvtColor(overlapMask,overlapMask,COLOR_BGR2GRAY);
|
|
|
|
|
/*cv::cvtColor(overlapMask,overlapMask,COLOR_BGR2GRAY);
|
|
|
|
|
cv::cvtColor(roiMask,roiMask,COLOR_BGR2GRAY);
|
|
|
|
|
cv::cvtColor(imgWarpedMask,imgWarpedMask,COLOR_BGR2GRAY);
|
|
|
|
|
cv::cvtColor(roi,roi,COLOR_BGR2GRAY);
|
|
|
|
|
cv::cvtColor(resultWarp,resultWarp,COLOR_BGR2GRAY);
|
|
|
|
|
cv::cvtColor(resultWarp,resultWarp,COLOR_BGR2GRAY);*/
|
|
|
|
|
|
|
|
|
|
//the blending function is DistanceTransform(img1)/(DT(img1)+DT(img2)) - DT is created from the masks
|
|
|
|
|
distanceTransform(roiMask,roiDT,DIST_L2, 3);
|
|
|
|
@ -710,7 +826,7 @@ class PointBase {
|
|
|
|
|
|
|
|
|
|
normalize(resultRoi, resultRoi, 0.0, 1.0, NORM_MINMAX);
|
|
|
|
|
imshow("resultRoi", resultRoi);
|
|
|
|
|
cv::waitKey(0);
|
|
|
|
|
//cv::waitKey(0);
|
|
|
|
|
|
|
|
|
|
//cv::cvtColor(roiMask,roiMask,COLOR_GRAY2BGR);
|
|
|
|
|
//cout<<cv::typeToString(roiMask.type())<< "img TYPE \n";
|
|
|
|
@ -721,12 +837,14 @@ class PointBase {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
normalize(resultRoi, resultRoi, 0.0, 255.0, NORM_MINMAX);
|
|
|
|
|
cv::cvtColor(resultRoi,resultRoi,COLOR_GRAY2BGR);
|
|
|
|
|
//cv::cvtColor(resultRoi,resultRoi,COLOR_GRAY2BGR);
|
|
|
|
|
resultRoi.copyTo(img(Rect(xLoc, yLoc, xWitdth, yHeight)));
|
|
|
|
|
imwrite("AAAAAAA.png", img);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
destroyAllWindows();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//cout<<CV_VERSION;
|
|
|
|
|
}
|
|
|
|
@ -737,6 +855,7 @@ class PointBase {
|
|
|
|
|
}
|
|
|
|
|
logFile.close();
|
|
|
|
|
string resultName = "result" + to_string(imgIdx) +".png";
|
|
|
|
|
cout<<"ROIS: " <<roiCounter << "\n PlacedImgs: " <<placeCounter <<"\n tempMatches: " << tempMatchCounter <<'\n';
|
|
|
|
|
//imshow("fag",img);
|
|
|
|
|
//waitKey(0);
|
|
|
|
|
//imwrite(resultName, img);
|
|
|
|
@ -775,4 +894,615 @@ class PointBase {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void patternMatchTry(int imgW,int imgH)
|
|
|
|
|
{
|
|
|
|
|
int imgWidth = imgW;
|
|
|
|
|
int imgHeight = imgH;
|
|
|
|
|
if (imgWidth > 1000)
|
|
|
|
|
{
|
|
|
|
|
imgWidth = int(0.4*imgWidth);
|
|
|
|
|
imgHeight = int(0.4*imgHeight);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector <double> edges;
|
|
|
|
|
edges = getEdgeValues();
|
|
|
|
|
double minX=edges[0];
|
|
|
|
|
double maxX=edges[1];
|
|
|
|
|
double minY=edges[2];
|
|
|
|
|
double maxY=edges[3];
|
|
|
|
|
|
|
|
|
|
int windowHeight = (int)(maxY*(imgHeight/imgHeightDeg))+imgHeight*2;
|
|
|
|
|
int windowWidth = (int)((360/imgWidthDeg)*imgWidth) + imgWidth;
|
|
|
|
|
|
|
|
|
|
Mat img = Mat::zeros(windowHeight,windowWidth,CV_8UC1);
|
|
|
|
|
rectangle(img,Point(3,3),Point(15,15),Scalar(128,128, 0),2,2,0);
|
|
|
|
|
|
|
|
|
|
int imgIdx = 0;
|
|
|
|
|
//main loop
|
|
|
|
|
while (!points.empty())
|
|
|
|
|
{
|
|
|
|
|
//take the first point from the left and find adjts. to it
|
|
|
|
|
Point2d p = points[0];
|
|
|
|
|
vector<Point2d> stitchQueue;
|
|
|
|
|
stitchQueue.push_back(p);
|
|
|
|
|
points.erase(points.begin());
|
|
|
|
|
|
|
|
|
|
vector<Point2d> temp = getAdjacents(p); //find adj. of first point - inits toDo vector
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (toDoVector.empty()) //if first point has no adjts. - log him as singleton
|
|
|
|
|
{
|
|
|
|
|
ofstream singletonsFile("singletons.log", ios_base::app);
|
|
|
|
|
if(!singletonsFile)
|
|
|
|
|
{
|
|
|
|
|
singletonsFile << "x: " << p.x << std::endl;
|
|
|
|
|
singletonsFile << "y: " << p.y << std::endl;
|
|
|
|
|
singletonsFile << pathMap[Point2d(p.x,p.y) ] << std::endl;
|
|
|
|
|
singletonsFile.close();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ofstream sing;
|
|
|
|
|
sing.open("singletons.log",ios_base::app);
|
|
|
|
|
sing << "x: " << p.x << std::endl;
|
|
|
|
|
sing << "y: " << p.y << std::endl;
|
|
|
|
|
sing << pathMap[Point2d(p.x,p.y) ] << std::endl;
|
|
|
|
|
sing.close();
|
|
|
|
|
}
|
|
|
|
|
stitchQueue.pop_back();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//finds adjacencies to every point
|
|
|
|
|
while(!toDoVector.empty())
|
|
|
|
|
{
|
|
|
|
|
Point2d p2 = toDoVector[0];
|
|
|
|
|
stitchQueue.push_back(p2);
|
|
|
|
|
temp = getAdjacents(p2);
|
|
|
|
|
toDoVector.erase(toDoVector.begin());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//stitching
|
|
|
|
|
// Define object to store the stitched image
|
|
|
|
|
/* a funct was created for this, see getEdgeValues()
|
|
|
|
|
double minX=999;
|
|
|
|
|
double maxX=0;
|
|
|
|
|
double minY=900000;
|
|
|
|
|
double maxY=0;
|
|
|
|
|
|
|
|
|
|
for (Point2d coords: stitchQueue)
|
|
|
|
|
{
|
|
|
|
|
if (coords.x < minX) minX=coords.x;
|
|
|
|
|
if (coords.x > maxX) maxX=coords.x;
|
|
|
|
|
if (coords.y < minY) minY=coords.y;
|
|
|
|
|
if (coords.y > maxY) maxY=coords.y;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int xDiff = (int)round(maxX)-(int)round(minX);
|
|
|
|
|
int yDiff = (int)round(maxY)-(int)round(minY);
|
|
|
|
|
cout <<xDiff <<"\n";
|
|
|
|
|
cout <<yDiff <<"\n";
|
|
|
|
|
|
|
|
|
|
//img creation put to beginning of funcion
|
|
|
|
|
/*
|
|
|
|
|
Mat img = Mat::zeros((int)(maxY*(imgHeight/imgHeightDeg))+imgHeight,(int)((360/imgWidthDeg)*imgWidth) + imgWidth,CV_8UC3);
|
|
|
|
|
rectangle(img,Point(3,3),Point(15,15),Scalar(128,128, 0),2,2,0);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//open stream for logging
|
|
|
|
|
string logFileName = to_string(imgIdx) + ".log";
|
|
|
|
|
ofstream logFile(logFileName);
|
|
|
|
|
int qIdx = 0;
|
|
|
|
|
for (Point2d coords: stitchQueue)
|
|
|
|
|
{
|
|
|
|
|
//log which images are in which result file
|
|
|
|
|
logFile << "x: " << coords.x << std::endl;
|
|
|
|
|
logFile << "y: " << coords.y << std::endl;
|
|
|
|
|
logFile << pathMap[Point2d(coords.x,coords.y) ] << std::endl;
|
|
|
|
|
|
|
|
|
|
//log to stdout
|
|
|
|
|
cout << "x: " << coords.x << std::endl;
|
|
|
|
|
cout << "y: " << coords.y << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string jsonPath = pathMap[coords];
|
|
|
|
|
string pngPath = jsonPath.erase(jsonPath.length()-4);
|
|
|
|
|
pngPath = pngPath + "png";
|
|
|
|
|
cout << "file: " << pngPath << std::endl;
|
|
|
|
|
|
|
|
|
|
Mat imgSmall = imread(pngPath,IMREAD_GRAYSCALE);
|
|
|
|
|
resize(imgSmall, imgSmall, Size(imgWidth, imgHeight), INTER_LINEAR);
|
|
|
|
|
|
|
|
|
|
Ptr<CLAHE> clahe = cv::createCLAHE(4.0, cv::Size(8,8));
|
|
|
|
|
clahe->apply(imgSmall,imgSmall);
|
|
|
|
|
cout<< cv::typeToString( imgSmall.type() );
|
|
|
|
|
|
|
|
|
|
cout <<minX <<"\n";
|
|
|
|
|
cout <<minY <<"\n";
|
|
|
|
|
|
|
|
|
|
//cout << (int)round(coords.x)-(int)round(minX)<< "\n";
|
|
|
|
|
//cout << (int)round(coords.y)-(int)round(minY)<< "\n";
|
|
|
|
|
cout << (int)round(coords.y)*(int)(imgHeight/imgHeightDeg)<< "\n";
|
|
|
|
|
|
|
|
|
|
//first image is added to result img, others will be stitched
|
|
|
|
|
if (qIdx==0)
|
|
|
|
|
{
|
|
|
|
|
imgSmall.copyTo(img(cv::Rect((int)round(coords.x)*(int)(imgWidth/imgWidthDeg),(int)round(coords.y)*(int)(imgHeight/imgHeightDeg),imgSmall.cols, imgSmall.rows)));
|
|
|
|
|
cout<<"DINGUS WAS PLACED \n";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
//default ROI location and size
|
|
|
|
|
int xLoc=(int)round(coords.x)*(int)(imgWidth/imgWidthDeg) - imgWidth; //=normalized x-coord. minus 1 width of image
|
|
|
|
|
int yLoc=(int)round(coords.y)*(int)(imgHeight/imgHeightDeg) - imgHeight;
|
|
|
|
|
int xWitdth=3*imgWidth;
|
|
|
|
|
int yHeight=3*imgHeight;
|
|
|
|
|
|
|
|
|
|
//edge cases
|
|
|
|
|
if ((int)round(coords.x)*(int)(imgWidth/imgWidthDeg) - imgWidth < 0) xLoc=0;
|
|
|
|
|
if ((int)round(coords.y)*(int)(imgHeight/imgHeightDeg) - imgHeight < 0) yLoc = 0;
|
|
|
|
|
if (xLoc + xWitdth > windowWidth) xWitdth = windowWidth - xLoc;
|
|
|
|
|
if (yLoc + yHeight > windowHeight) yHeight = windowHeight - yLoc;
|
|
|
|
|
|
|
|
|
|
//create the ROI
|
|
|
|
|
Mat roi; //we dont need to apply CLAHE to ROI, since it consists of images which have clahe already applied
|
|
|
|
|
roi = img(Rect(xLoc, yLoc, xWitdth, yHeight));
|
|
|
|
|
|
|
|
|
|
Mat roiEdit, imgSmallEdit;
|
|
|
|
|
roiEdit = roi.clone();
|
|
|
|
|
imgSmallEdit = imgSmall.clone();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GaussianBlur(roi, roiEdit, Size(3, 3), 0);
|
|
|
|
|
GaussianBlur(imgSmall, imgSmallEdit, Size(3, 3), 0);
|
|
|
|
|
|
|
|
|
|
Canny(roiEdit, roiEdit, 100, 200, 3, false);
|
|
|
|
|
Canny(imgSmallEdit, imgSmallEdit, 100, 200, 3, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//vector<Mat> rectHolder;
|
|
|
|
|
//Mat rect1,rect2,rect3,rect4,rect5;
|
|
|
|
|
int rectH = imgSmall.rows, rectW = imgSmall.cols;
|
|
|
|
|
/*
|
|
|
|
|
Point2d coord1 = Point2d(int(imgWidth*0.1),int(imgHeight*0.1));
|
|
|
|
|
Point2d coord2 = Point2d(int(imgWidth*0.1),int(imgHeight*0.7));
|
|
|
|
|
Point2d coord3 = Point2d(int(imgWidth*0.5),int(imgHeight*0.5));
|
|
|
|
|
Point2d coord4 = Point2d(int(imgWidth*0.7),int(imgHeight*0.2));
|
|
|
|
|
Point2d coord5 = Point2d(int(imgWidth*0.7),int(imgHeight*0.7));
|
|
|
|
|
*/
|
|
|
|
|
//vector<Point2d> coordRects;
|
|
|
|
|
/*
|
|
|
|
|
coordRects.push_back(coord1);
|
|
|
|
|
coordRects.push_back(coord2);
|
|
|
|
|
coordRects.push_back(coord3);
|
|
|
|
|
coordRects.push_back(coord4);
|
|
|
|
|
coordRects.push_back(coord5);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
vector<Point2d> coordRects;
|
|
|
|
|
vector<Mat> rects;
|
|
|
|
|
|
|
|
|
|
for (int y= 0; y<imgSmall.rows - rectH; y=y+10)
|
|
|
|
|
{
|
|
|
|
|
for (int x=0 ; x< imgSmall.cols - rectW; x = x+10)
|
|
|
|
|
{
|
|
|
|
|
Point2d currentPoint = Point2d(x,y);
|
|
|
|
|
coordRects.push_back(currentPoint);
|
|
|
|
|
|
|
|
|
|
rects.push_back(imgSmallEdit(Rect(currentPoint.x,currentPoint.y,rectW,rectH)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cout << "RECTS DONE \n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<Mat> results;
|
|
|
|
|
double min_val, max_val;
|
|
|
|
|
Point min_loc, max_loc;
|
|
|
|
|
double globMax = 0.0;
|
|
|
|
|
int minIDX = 0;
|
|
|
|
|
Mat result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < rects.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
matchTemplate(roiEdit,rects[i],result,TM_CCOEFF);
|
|
|
|
|
results.push_back(result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
minMaxLoc(result,&min_val,&max_val,&min_loc,&max_loc);
|
|
|
|
|
if (max_val>globMax)
|
|
|
|
|
{
|
|
|
|
|
globMax=max_val;
|
|
|
|
|
minIDX = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
minMaxLoc(results[minIDX],&min_val,&max_val,&min_loc,&max_loc);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cout << "SIZE:"<< results[minIDX].size() << '\n';
|
|
|
|
|
cout << "IDX:" << minIDX << "\n";
|
|
|
|
|
*/
|
|
|
|
|
//min_loc is the top left of the best of the five sub-rois
|
|
|
|
|
//the top left of where to put the small img is min_loc - coordrects[minIDX]
|
|
|
|
|
|
|
|
|
|
Mat result;
|
|
|
|
|
double min_val, max_val;
|
|
|
|
|
Point min_loc, max_loc;
|
|
|
|
|
matchTemplate(roiEdit,imgSmallEdit,result,TM_CCOEFF);
|
|
|
|
|
minMaxLoc(result,&min_val,&max_val,&min_loc,&max_loc);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//debug stuff
|
|
|
|
|
Mat roiWithLocation, chosenSmallRoiImg;
|
|
|
|
|
imshow("matchResult",result);
|
|
|
|
|
roiWithLocation= roiEdit.clone();
|
|
|
|
|
chosenSmallRoiImg = imgSmallEdit.clone();
|
|
|
|
|
rectangle(roiWithLocation,max_loc,Point(max_loc.x+rectW,max_loc.y+rectH),Scalar(128,128, 0),2,2,0);
|
|
|
|
|
rectangle(chosenSmallRoiImg,max_loc,Point(rectW,rectH),Scalar(128,128, 0),2,2,0);
|
|
|
|
|
imshow("roiWithLocation",roiWithLocation);
|
|
|
|
|
imshow("chosenSmallRoiImg",chosenSmallRoiImg);
|
|
|
|
|
|
|
|
|
|
//cout<<"HOW MANY RECTS " <<rects.size() <<"\n";
|
|
|
|
|
cout<<"Location in roi X:" << max_loc.x << " Y " << max_loc.y << "\n";
|
|
|
|
|
//imshow("chosen smallROI", rects[minIDX]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mat roiMask, roiDT, imgWarpedMask,imgDT,roiMaskFinal,imgMaskFinal,imgNew;
|
|
|
|
|
threshold(roi,roiMask,1,255,CV_8U);
|
|
|
|
|
imgWarpedMask = Mat::zeros(roi.rows,roi.cols,CV_8U);
|
|
|
|
|
imgWarpedMask(Rect(max_loc.x,max_loc.y,rectW,rectH))=1.0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
distanceTransform(roiMask,roiDT,DIST_L2, 3);
|
|
|
|
|
distanceTransform(imgWarpedMask,imgDT,DIST_L2, 3);
|
|
|
|
|
normalize(roiDT, roiDT, 0.0, 1.0, NORM_MINMAX);
|
|
|
|
|
normalize(imgDT, imgDT, 0.0, 1.0, NORM_MINMAX);
|
|
|
|
|
|
|
|
|
|
cv::divide(roiDT,(roiDT+imgDT),roiMaskFinal);
|
|
|
|
|
cv::divide(imgDT,(roiDT+imgDT),imgMaskFinal);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
normalize(roiMaskFinal, roiMaskFinal, 0.0, 255.0, NORM_MINMAX);
|
|
|
|
|
normalize(imgMaskFinal, imgMaskFinal, 0.0, 255.0, NORM_MINMAX);
|
|
|
|
|
imgNew = Mat::zeros(roi.rows,roi.cols,CV_8U);
|
|
|
|
|
imgSmall.copyTo(imgNew(Rect(max_loc.x , max_loc.y , rectW,rectH)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
roiMaskFinal.convertTo(roiMaskFinal,CV_8UC1);
|
|
|
|
|
imgMaskFinal.convertTo(imgMaskFinal,CV_8UC1);
|
|
|
|
|
roi.convertTo(roi,CV_32FC1);
|
|
|
|
|
imgNew.convertTo(imgNew,CV_32FC1);
|
|
|
|
|
roiMaskFinal.convertTo(roiMaskFinal,CV_32FC1);
|
|
|
|
|
imgMaskFinal.convertTo(imgMaskFinal,CV_32FC1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
multiply(roiMaskFinal,roi,roi);
|
|
|
|
|
cout<<cv::typeToString(imgMaskFinal.type())<< "imgMaskFinal TYPE \n";
|
|
|
|
|
cout<<cv::typeToString(imgNew.type())<< "imgNew TYPE \n";
|
|
|
|
|
|
|
|
|
|
multiply(imgMaskFinal,imgNew,imgNew);
|
|
|
|
|
|
|
|
|
|
cv::add(roi,imgNew, roi);
|
|
|
|
|
normalize(roi, roi, 0.0, 1.0, NORM_MINMAX);
|
|
|
|
|
imshow("roiafter",roi);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//uncomment this and comment from neareast Mat in order to disable blending
|
|
|
|
|
//imgSmall.copyTo(roi(Rect(max_loc.x , max_loc.y , rectW,rectH)));
|
|
|
|
|
//imshow("roiafter",roi);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
normalize(roi, roi, 0.0, 255.0, NORM_MINMAX);
|
|
|
|
|
roi.copyTo(img(Rect(xLoc, yLoc, xWitdth, yHeight)));
|
|
|
|
|
|
|
|
|
|
imwrite("roiafter.jpg",roi);
|
|
|
|
|
waitKey(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//cout<<CV_VERSION;
|
|
|
|
|
}
|
|
|
|
|
//if(qIdx==2) break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qIdx++;
|
|
|
|
|
}
|
|
|
|
|
logFile.close();
|
|
|
|
|
string resultName = "result" + to_string(imgIdx) +".png";
|
|
|
|
|
//imshow("fag",img);
|
|
|
|
|
//waitKey(0);
|
|
|
|
|
//imwrite(resultName, img);
|
|
|
|
|
//imgIdx++;
|
|
|
|
|
|
|
|
|
|
//stitching
|
|
|
|
|
/*
|
|
|
|
|
cout << "Stitching" << std::endl;
|
|
|
|
|
Stitcher::Status status = stitcher->stitch(imgs, pano);
|
|
|
|
|
if (status != Stitcher::OK)
|
|
|
|
|
{
|
|
|
|
|
// Check if images could not be stitched
|
|
|
|
|
// status is OK if images are stitched successfully
|
|
|
|
|
cout << "Can't stitch images\n";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
string resultName = "result" + to_string(imgIdx) +".jpg";
|
|
|
|
|
|
|
|
|
|
// Store a new image stitched from the given
|
|
|
|
|
//set of images as "result.jpg"
|
|
|
|
|
imwrite(resultName, pano);
|
|
|
|
|
|
|
|
|
|
// Show the result
|
|
|
|
|
imshow(resultName, pano);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
waitKey(0);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
imwrite("result0GIOJSDFI.png", img);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|