Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <opencv2/highgui/highgui.hpp>
00036 #include <aruco/aruco.h>
00037 #include <iostream>
00038 #include <aruco/arucofidmarkers.h>
00039 using namespace cv;
00040 using namespace std;
00041
00042 int HammDist_(const cv::Mat &m1,const cv::Mat & m2)
00043 {
00044
00045 int dist=0;
00046 for (int y=0;y<5;y++)
00047 for (int x=0;x<5;x++)
00048 if (m1.at<uchar>(y,x)!=m2.at<uchar>(y,x)) dist++;
00049 return dist;
00050
00051 }
00052 Mat rotate(Mat in)
00053 {
00054 Mat out;
00055 in.copyTo(out);
00056 for (int i=0;i<in.rows;i++)
00057 {
00058 for (int j=0;j<in.cols;j++)
00059 {
00060 out.at<uchar>(i,j)=in.at<uchar>(in.cols-j-1,i);
00061 }
00062 }
00063 return out;
00064 }
00065
00066
00067 int HammDist(const cv::Mat &m1,const cv::Mat & m2)
00068 {
00069 cv::Mat mc=m1.clone();
00070 int minD=std::numeric_limits<int>::max();
00071 for(int i=0;i<4;i++){
00072 int dist=HammDist_(mc,m2);
00073 if( dist<minD) minD=dist;
00074 mc= rotate(mc);
00075 }
00076 return minD;
00077
00078 }
00079
00080 int entropy(const cv::Mat &marker)
00081 {
00082
00083
00084 int totalEntropy=0;
00085 for (int y=0;y<5;y++)
00086 for (int x=0;x<5;x++){
00087 int minX=max(x-1,0);
00088 int maxX=min(x+1,5);
00089 int minY=max(y-1,0);
00090 int maxY=min(y+1,5);
00091
00092 for(int yy=minY;yy<maxY;yy++)
00093 for(int xx=minX;xx<maxX;xx++)
00094 if (marker.at<uchar>(y,x)!=marker.at<uchar>(yy,xx)) totalEntropy++;
00095 }
00096
00097 return totalEntropy;
00098 }
00099
00100 int main(int argc,char **argv)
00101 {
00102 try {
00103 if (argc<4) {
00104
00105
00106 cerr<<"Usage: nofMarkers outbasename size [minimum_entropy(9,25)]"<<endl;
00107 return -1;
00108 }
00109
00110
00111
00112 int minimimEntropy=0;
00113 if(argc>=5) minimimEntropy=atoi(argv[4]);
00114 vector<cv::Mat> markers;
00115 vector<int> ventropy;
00116 for (int i=0;i<1024;i++){
00117 markers.push_back(aruco::FiducidalMarkers::getMarkerMat(i) );
00118 ventropy.push_back(entropy( aruco::FiducidalMarkers::getMarkerMat(i) ));
00119 }
00120 cout<<"Calculating distance matrix"<<endl;
00121
00122 cv::Mat distances=cv::Mat::zeros(1024,1024,CV_32SC1);
00123 for (int i=0;i<1024;i++)
00124 for (int j=i+1;j<1024;j++)
00125 distances.at<int>(i,j)=distances.at<int>(j,i)= HammDist ( markers[i],markers[j]);
00126 cout<<"done"<<endl;
00127
00128 int nMarkers=atoi(argv[1]);
00129
00130 vector<bool> usedMarkers(1024,false);
00131
00132
00133
00134 vector<int> selectedMarkers;
00135
00136 int bestEntr=0;
00137 for(size_t i=0;i<ventropy.size();i++)
00138 if (ventropy[i]>ventropy[bestEntr]) bestEntr=i;
00139 selectedMarkers.push_back(bestEntr);
00140 usedMarkers[bestEntr]=true;
00141
00142
00143
00144 for(size_t i=0;i<ventropy.size();i++)
00145 if (ventropy[i]<minimimEntropy) usedMarkers[i]=true;
00146
00147 cout<<"Max Entroy in ="<<bestEntr<<" "<<ventropy[bestEntr]<<endl;
00148
00149 for (int i=1;i<nMarkers;i++) {
00150 int bestMarker=-1;
00151 int shorterDist=0;
00152
00153 for (int j=0;j<distances.cols;j++) {
00154 if (!usedMarkers[j]) {
00155 int minDist=std::numeric_limits< int >::max();
00156 for (size_t k=0;k<selectedMarkers.size();k++)
00157 if (distances.at<int> ( selectedMarkers[k], j)<minDist) minDist=distances.at<int> ( selectedMarkers[k], j);
00158
00159 if (minDist>shorterDist){
00160 shorterDist=minDist;
00161 bestMarker=j;
00162 }
00163 }
00164 }
00165 if (bestMarker!=-1 && shorterDist>1 ){
00166 selectedMarkers.push_back(bestMarker);
00167 usedMarkers[bestMarker]=true;
00168
00169 }
00170 else {cerr<<"COUDL NOT ADD ANY MARKER"<<endl;exit(0);}
00171
00172 }
00173
00174 sort(selectedMarkers.begin(),selectedMarkers.end());
00175 for(size_t i=0;i<selectedMarkers.size();i++){
00176 char name[1024];
00177 sprintf(name,"%s%d.png",argv[2],selectedMarkers[i]);
00178
00179 cout<<selectedMarkers[i]<<" "<<flush;
00180 Mat markerImage=aruco::FiducidalMarkers::createMarkerImage(selectedMarkers[i],atoi(argv[3]));
00181 imwrite(name,markerImage);
00182 }
00183 cout<<endl;
00184
00185 int minDist=std::numeric_limits<int>::max();
00186 for(size_t i=0;i<selectedMarkers.size()-1;i++)
00187 for(size_t j=i+1;j<selectedMarkers.size();j++){
00188
00189 if (distances.at<int> ( selectedMarkers[i], selectedMarkers[j]) < minDist) minDist=distances.at<int> ( selectedMarkers[i], selectedMarkers[j]);
00190
00191 }
00192
00193
00194 cout<<"Min Dist="<<minDist<<endl;
00195
00196 }
00197 catch (std::exception &ex)
00198 {
00199 cout<<ex.what()<<endl;
00200 }
00201
00202 }
00203