├── README.md ├── birdView.hpp ├── cpp └── calibrationProgram.cpp ├── img ├── 0.png ├── 1.png ├── 2.png ├── 3.png ├── ParamSetting.png ├── info.txt └── ok.png └── main.cpp /README.md: -------------------------------------------------------------------------------- 1 | # BirdViewTransform 2 | Put FOUR image (or video stream )from 4 different directions together, and form them into a bird view **by pointing out 4 corner in 4 direc pic**. 3 | 4 | ## About 5 | 6 | I have four imgs, such as(from up to down: **left**, **forward**, **right**, **backward**) 7 | 8 | ![Left](img/0.png) 9 | 10 | ![Forward](img/1.png) 11 | 12 | ![Right](img/2.png) 13 | 14 | ![Backward](img/3.png) 15 | 16 | using this programe, we can get 17 | 18 | ![after transform](img/ok.png) 19 | 20 | ## parameters setting 21 | Meanings of functions from this *Class BirhView* are shown as figure follow: 22 | 23 | ![param setting](img/ParamSetting.png) 24 | 25 | Before using this API Class, be awared you have had known that accurated measure is need for better visual effect and making image be exact 26 | 27 | ## other 28 | 29 | Before birdEye transform, Calibration of camera is needed! here is a [link](http://tanzby.cn/2017/08/01/%E5%9F%BA%E4%BA%8EopenCV%E7%9A%84%E7%9B%B8%E6%9C%BA%E6%A0%A1%E6%AD%A3%E7%A8%8B%E5%BA%8F/) for calibration. 30 | -------------------------------------------------------------------------------- /birdView.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tanzby on 17-8-30. 3 | // 4 | 5 | #ifndef BIRDVIEW_HPP 6 | #define BIRDVIEW_HPP 7 | 8 | #include 9 | #include 10 | using namespace cv; 11 | using namespace std; 12 | 13 | // calculate correspondence point for every input 14 | // 0: left up 1: right up 2:rigth down 3: left down 15 | 16 | 17 | class BirdView 18 | { 19 | public: 20 | BirdView(const char* configFile = NULL) 21 | { 22 | SourcePoint_OK=ParamSet_OK = false; 23 | maskHeigth = clickCount = camID = 0; 24 | targetPoint.resize(4); 25 | sourcePoint.resize(4); 26 | try 27 | { 28 | carPic = imread("../img/car.jpg",CV_8UC4); 29 | } 30 | catch (...) 31 | { 32 | std::cout <<"[WARNING] Car model view pic not found!\n"; 33 | } 34 | for (int i = 0;i < 4; i++) 35 | { 36 | targetPoint[i].resize(4); 37 | sourcePoint[i].resize(4); 38 | } 39 | // check if config file exist. 40 | if (configFile) 41 | { 42 | readConfig(configFile); 43 | } 44 | } 45 | void setInternalShift(int W, int H) 46 | { 47 | ShiftAdjust = Size(W,H); 48 | ParamSet_OK = false; 49 | setParam(); 50 | } 51 | void setShift(int W, int H) 52 | { 53 | Shift = Size(W,H); 54 | ParamSet_OK = false; 55 | setParam(); 56 | } 57 | void setCarSize(int W,int H) 58 | { 59 | carSize = Size(W, H); 60 | ParamSet_OK = false; 61 | setParam(); 62 | } 63 | void setChessSize(int W, int H) 64 | { 65 | chessBordWidth.width = W; 66 | chessBordWidth.height = H; 67 | ParamSet_OK = false; 68 | setParam(); 69 | } 70 | void setMaskHeigth(int maskHeigth_) 71 | { 72 | maskHeigth = maskHeigth_; 73 | ParamSet_OK = false; 74 | setParam(); 75 | } 76 | Mat transformView(Mat* v) 77 | { 78 | if (!SourcePoint_OK) 79 | { 80 | std::cerr<<"[ERROR] Source Points have not been pointed! please Add function sourcePointClick to get Source Points!\n"; 81 | throw "[ERROR] Source Points have not been pointed! please Add function sourcePointClick to get Source Points!\n"; 82 | } 83 | if (!ParamSet_OK) 84 | { 85 | setParam(); 86 | } 87 | 88 | Mat b[4]; 89 | Mat m = Mat(mSize, CV_8UC3 ); 90 | int seq[4] = { 0,2,1,3 }; 91 | for (int i = 0; i < 4; i++) 92 | { 93 | if(!v[seq[i]].data) 94 | { 95 | continue; 96 | } 97 | warpPerspective(v[seq[i]], b[seq[i]], Birdtransform[seq[i]], mSize); 98 | switch (seq[i]) 99 | { 100 | case 1: 101 | b[seq[i]](r[seq[i]]).copyTo(m(r[seq[i]]), maskF); 102 | break; 103 | case 3: 104 | b[seq[i]](r[seq[i]]).copyTo(m(r[seq[i]]), maskB); 105 | break; 106 | default: 107 | b[seq[i]](r[seq[i]]).copyTo(m(r[seq[i]])); 108 | break; 109 | } 110 | } 111 | if(carPic.data) carPicTmp.copyTo(m(carPicPos)); 112 | //drawing target points 113 | const Scalar color[4] = { Scalar(255,0,0),Scalar(0,255,0), Scalar(255,255,0), Scalar(0,255,255) }; 114 | for (int i = 0; i < 16; i++) circle(m, targetPoint[i / 4][i % 4], 5, color[i / 4], 5); 115 | return m; 116 | } 117 | void saveConfig(const char* configFile = "config.yml") 118 | { 119 | for (int i = 0;i < 4; i++) 120 | { 121 | if (sourcePoint[i].empty()) 122 | { 123 | std::cout << "[ERROR] sourcePoint has not been comfired all\n"<> sourcePoint[i][k]; 155 | } 156 | } 157 | SourcePoint_OK = true; // source point reading completed 158 | ParamSet_OK = false; // setting parma 159 | setParam(); 160 | std::cout << "[WARNING] Config file read sucessfully!\n"; 161 | } 162 | else std::cout << "[WARNING] There is not a config file in folder\n"; 163 | } 164 | void sourcePointClick(Mat *v) 165 | { 166 | setParam(1); 167 | // click corner-points and record them 168 | printf("cam: %d ,pointID: %d ", camID, clickCount); 169 | const char *windowsName = "Source point set"; 170 | namedWindow(windowsName); 171 | setMouseCallback(windowsName,on_MouseHandle, (void*)this); 172 | for(int i=0;i<4;i++) 173 | { 174 | for(int j=0;j<4;j++) 175 | { 176 | sourcePoint[i][j]= Point2f(0,0); 177 | } 178 | } 179 | 180 | for (camID = 0, clickCount = 0; camID<4;) 181 | { 182 | for (int i = 0; i < sourcePoint[camID].size(); i++) 183 | { 184 | circle(v[camID], sourcePoint[camID][i], 5, Scalar(255, 0, 0), 2); 185 | } 186 | imshow(windowsName, v[camID]); 187 | if (waitKey(20) == 'j') break; 188 | } 189 | setMouseCallback(windowsName, NULL, NULL); 190 | destroyWindow(windowsName); 191 | saveConfig("config.yml");/*save source's points*/ 192 | SourcePoint_OK = true; 193 | } 194 | void sourcePointClick(cv::VideoCapture *v) 195 | { 196 | setParam(1); 197 | Mat ans; 198 | // click corner-points and record them 199 | printf("cam: %d ,pointID: %d ", camID, clickCount); 200 | const char *windowsName = "Source point set"; 201 | namedWindow(windowsName); 202 | setMouseCallback(windowsName,on_MouseHandle, (void*)this); 203 | for(int i=0;i<4;i++) 204 | { 205 | sourcePoint[i].clear(); 206 | } 207 | for (camID = 0, clickCount = 0; camID<4;) 208 | { 209 | v[camID] >> ans; 210 | for (int i = 0; i < sourcePoint[camID].size(); i++) 211 | { 212 | circle(ans, sourcePoint[camID][i], 5, Scalar(255, 0, 0), 2); 213 | } 214 | imshow(windowsName, ans); 215 | if (waitKey(20) == 'j') break; 216 | } 217 | setMouseCallback(windowsName, NULL, NULL); 218 | destroyWindow(windowsName); 219 | saveConfig("config.yml");/*save source's points*/ 220 | SourcePoint_OK = true; 221 | } 222 | static void on_MouseHandle(int e, int x, int y, int flag, void* param) 223 | { 224 | BirdView & birdView = *(BirdView*)param; 225 | int camID = birdView.camID; 226 | switch (e) 227 | { 228 | case EVENT_LBUTTONUP: 229 | { 230 | birdView.sourcePoint[birdView.camID][birdView.clickCount] = Point2f(x, y) ; 231 | printf("x:%d y:%d\n", x, y); 232 | birdView.clickCount++; 233 | if (birdView.clickCount> 3) 234 | { 235 | birdView.clickCount = 0; 236 | birdView.Birdtransform[camID] = getPerspectiveTransform(birdView.sourcePoint[camID], birdView.targetPoint[camID]); 237 | birdView.camID++; 238 | } 239 | if (birdView.camID<3) 240 | { 241 | printf("cam: %d ,pointID: %d ", birdView.camID, birdView.clickCount); 242 | } 243 | else printf("\n"); 244 | } 245 | default: break; 246 | } 247 | } 248 | 249 | private: 250 | Rect r[4],carPicPos; 251 | int clickCount, camID, maskHeigth; 252 | Mat Birdtransform[4],maskF, maskB, carPic,carPicTmp; 253 | vector > targetPoint, sourcePoint; 254 | Size ShiftAdjust, Shift, chessBordWidth, mSize, carSize; 255 | bool SourcePoint_OK,ParamSet_OK; 256 | void setParam(bool tranformCheck = false) 257 | { 258 | //// WARMING will show when Transform is running but not all parameters have been set 259 | if (Shift.area()== 0) 260 | { 261 | if (tranformCheck)std::cout << "[WARMING] Shift has not been set! Default value will be used" << std::endl; 262 | Shift.width = Shift.height = 200; 263 | } 264 | if (chessBordWidth.area() == 0) 265 | { 266 | if (tranformCheck)std::cout << "[WARMING] chessBordWidth has not been set! Default value will be used" << std::endl; 267 | chessBordWidth.width = chessBordWidth.height = 60; 268 | } 269 | if (ShiftAdjust.area() == 0) 270 | { 271 | if (tranformCheck)std::cout << "[WARMING] ShiftAdjust has not been set! Default value will be used" << std::endl; 272 | ShiftAdjust.width = 36; 273 | ShiftAdjust.height = 27; 274 | } 275 | if (carSize.area() == 0) 276 | { 277 | if (tranformCheck)std::cout << "[WARMING] carSize has not been set! Default value will be used" << std::endl; 278 | carSize = Size(240, 380); 279 | } 280 | if (maskHeigth >=100 || maskHeigth <=0) 281 | { 282 | if (tranformCheck)std::cout << "[WARMING] maskHeigth has not been set! Default value will be used" << std::endl; 283 | maskHeigth = 200; 284 | } 285 | if (!ParamSet_OK) 286 | { 287 | /*The size of the entire output image*/ 288 | mSize = Size(Shift.width * 2 + carSize.width + chessBordWidth.width * 2, 289 | Shift.height * 2 + carSize.height + chessBordWidth.height * 2); 290 | /*make targetPoint, need chessBordWidth,mSize,Shift*/ 291 | /*left*/ 292 | targetPoint[0][0] = (Point2f(Shift.width + chessBordWidth.width, Shift.height)); 293 | targetPoint[0][1] = (Point2f(Shift.width + chessBordWidth.width, mSize.height - Shift.height)); 294 | targetPoint[0][2] = (Point2f(Shift.width, mSize.height - Shift.height)); 295 | targetPoint[0][3] = (Point2f(Shift.width, Shift.height)); 296 | 297 | /*forward*/ 298 | targetPoint[1][0] = (Point2f(mSize.width - Shift.width, Shift.height + chessBordWidth.height)); 299 | targetPoint[1][1] = (Point2f(Shift.width, Shift.height + chessBordWidth.height)); 300 | targetPoint[1][2] = (Point2f(Shift.width, Shift.height)); 301 | targetPoint[1][3] = (Point2f(mSize.width - Shift.width, Shift.height)); 302 | 303 | /*backward*/ 304 | targetPoint[3][0] = (Point2f(Shift.width, mSize.height - Shift.height - chessBordWidth.height)); 305 | targetPoint[3][1] = (Point2f(mSize.width - Shift.width, mSize.height - Shift.height - chessBordWidth.height)); 306 | targetPoint[3][2] = (Point2f(mSize.width - Shift.width, mSize.height - Shift.height)); 307 | targetPoint[3][3] = (Point2f(Shift.width, mSize.height - Shift.height)); 308 | /*right*/ 309 | targetPoint[2][0] = (Point2f(mSize.width - Shift.width - chessBordWidth.width, Shift.height)); 310 | targetPoint[2][1] = (Point2f(mSize.width - Shift.width - chessBordWidth.width, mSize.height - Shift.height)); 311 | targetPoint[2][2] = (Point2f(mSize.width - Shift.width, mSize.height - Shift.height)); 312 | targetPoint[2][3] = (Point2f(mSize.width - Shift.width, Shift.height)); 313 | 314 | //need Shift, chessBordWidth, ShiftAdjust, mSize 315 | /*roi*/ 316 | r[0] = Rect(0, 0, Shift.width + chessBordWidth.width + ShiftAdjust.width, mSize.height); 317 | r[1] = Rect(0, 0, mSize.width, Shift.height + chessBordWidth.height + ShiftAdjust.height); 318 | r[2] = Rect(mSize.width - Shift.width - chessBordWidth.width - ShiftAdjust.width, 0, Shift.width + chessBordWidth.width + ShiftAdjust.width, mSize.height); 319 | r[3] = Rect(0, mSize.height - Shift.width - chessBordWidth.width - ShiftAdjust.width, mSize.width, Shift.height + chessBordWidth.height + ShiftAdjust.height); 320 | 321 | maskF = Mat(r[1].size(), CV_8UC1, Scalar(1)); 322 | 323 | maskB = Mat(r[1].size(), CV_8UC1, Scalar(1)); 324 | 325 | /*make mask, need r */ 326 | vector > maskVec; 327 | /*forward*/ 328 | maskVec.push_back(vector()); 329 | maskVec[0].push_back(Point(0, r[1].height)); 330 | maskVec[0].push_back(Point(0, r[1].height - maskHeigth)); 331 | maskVec[0].push_back(Point(r[0].width, r[1].height)); 332 | maskVec.push_back(vector()); 333 | maskVec[1].push_back(Point(r[1].width, r[1].height)); 334 | maskVec[1].push_back(Point(r[1].width, r[1].height - maskHeigth)); 335 | maskVec[1].push_back(Point(r[1].width - r[2].width, r[1].height)); 336 | /*backward*/ 337 | maskVec.push_back(vector()); 338 | maskVec[2].push_back(Point(0, 0)); 339 | maskVec[2].push_back(Point(0, maskHeigth)); 340 | maskVec[2].push_back(Point(r[0].width, 0)); 341 | maskVec.push_back(vector()); 342 | maskVec[3].push_back(Point(mSize.width, 0)); 343 | maskVec[3].push_back(Point(mSize.width, maskHeigth)); 344 | maskVec[3].push_back(Point(mSize.width - r[2].width, 0)); 345 | /*draw mask*/ 346 | 347 | drawContours(maskF, maskVec, 0, Scalar(0), CV_FILLED); 348 | drawContours(maskF, maskVec, 1, Scalar(0), CV_FILLED); 349 | drawContours(maskB, maskVec, 2, Scalar(0), CV_FILLED); 350 | drawContours(maskB, maskVec, 3, Scalar(0), CV_FILLED); 351 | 352 | 353 | for (size_t i = 0; i < 4 ; i++) 354 | { 355 | Birdtransform[i] = getPerspectiveTransform(sourcePoint[i], targetPoint[i]); 356 | } 357 | 358 | if(carPic.data) 359 | { 360 | Size newCarSize = Size(carSize.width-2*ShiftAdjust.width,carSize.height-2*ShiftAdjust.height); 361 | resize(carPic,carPicTmp,newCarSize,CV_INTER_CUBIC); 362 | carPicPos = Rect(Shift.width+chessBordWidth.width+ShiftAdjust.width, 363 | Shift.height +chessBordWidth.height+ShiftAdjust.height, 364 | newCarSize.width,newCarSize.height); 365 | } 366 | 367 | ParamSet_OK = true; 368 | } 369 | } 370 | 371 | }; 372 | #endif //BIRDVIEW_HPP 373 | -------------------------------------------------------------------------------- /cpp/calibrationProgram.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define oo 1E9 6 | #define CAM_WIDTH 720 7 | #define CAM_HEIGTH 480 8 | #define OUTPUT_WIDTH 1024 9 | #define OUTPUT_HEIGTH 500 10 | #define WIDTH_ADJUST 90 11 | #define HEIGHT_ADJUST 0 12 | using namespace std; 13 | using namespace cv; 14 | 15 | int camID; 16 | //设置是否为鱼眼相机 17 | const bool FISH_EYE = true; 18 | 19 | const char * WINDOWSNAME = "ChessCatch"; 20 | //使用的抓取帧数目 21 | const int usedImageForCalib = 15; 22 | 23 | VideoCapture v; 24 | //棋盘点大小 25 | Size board_size = Size(4,6); 26 | //帧缓冲区域 27 | Mat imageBuf; 28 | mutex Mutex_imageBuf; 29 | // 任务是否完成标志 30 | bool missionFinish; 31 | mutex Mutex_missionFinish; 32 | // 是否找到棋盘标志 33 | bool patternFind; 34 | mutex Mutex_patternFind; 35 | 36 | vector corners; 37 | vector> corners_Seq; // 所有有效图片的点集合 38 | vector> object_Points; // 世界坐标集合 39 | 40 | Mat intrinsic_matrix; // 校正矩阵1 41 | Mat distortion_coeffs; // 校正矩阵2 42 | 43 | Mat mapx, mapy; // 映射矩阵 44 | 45 | void save() 46 | { 47 | char buf[32]; 48 | sprintf(buf, "data/CamCalibParma%d.yml", camID); 49 | FileStorage fs(buf, FileStorage::WRITE); 50 | if (fs.isOpened()) 51 | { 52 | write(fs, "camType", (FISH_EYE? "eyeCam":"normalCam")); 53 | write(fs,"intrinsic_matrix",intrinsic_matrix); 54 | write(fs, "distortion_coeffs", distortion_coeffs); 55 | fs.release(); 56 | cout << "\n param save complete! \n\n"; 57 | } 58 | } 59 | 60 | bool read() 61 | { 62 | char buf[32]; 63 | sprintf(buf, "data/CamCalibParma%d.yml", camID); 64 | FileStorage fs(buf, FileStorage::READ); 65 | if (fs.isOpened()) 66 | { 67 | fs["intrinsic_matrix"] >> intrinsic_matrix; 68 | fs["distortion_coeffs"] >> distortion_coeffs; 69 | /*fs["mapx"] >> mapx; 70 | fs["mapy"] >> mapy;*/ 71 | Mat R = Mat::eye(3, 3, CV_32F); 72 | Mat newIn; 73 | intrinsic_matrix.copyTo(newIn); 74 | newIn.at(0, 2) = OUTPUT_WIDTH / 2 - WIDTH_ADJUST; 75 | newIn.at(1, 2) = OUTPUT_HEIGTH / 2 - HEIGHT_ADJUST; 76 | if (FISH_EYE) 77 | fisheye::initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R, newIn, Size(OUTPUT_WIDTH,OUTPUT_HEIGTH ), CV_32FC1, mapx, mapy); 78 | else 79 | initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R, newIn, Size(OUTPUT_WIDTH, OUTPUT_HEIGTH), CV_32FC1, mapx, mapy); 80 | 81 | cout << "\n param read complete! \n\n"; 82 | return true; 83 | } 84 | return false; 85 | } 86 | 87 | void display(bool calibrationed = 0) 88 | { 89 | while (1) 90 | { 91 | unique_lock lock_1(Mutex_missionFinish), lock_2(Mutex_imageBuf); 92 | v >> imageBuf; 93 | 94 | if(calibrationed) 95 | remap(imageBuf, imageBuf, mapx, mapy, CV_INTER_LINEAR); 96 | imshow(WINDOWSNAME, imageBuf); 97 | lock_2.unlock(); 98 | if (missionFinish) 99 | { 100 | destroyWindow(WINDOWSNAME); 101 | break; 102 | } 103 | lock_1.unlock(); 104 | waitKey(2); 105 | } 106 | } 107 | 108 | void chessCheck(int num) 109 | { 110 | missionFinish = false; //任务开始标志 111 | 112 | thread([] {display(0); }).detach(); // 用来显示实时图像 113 | 114 | thread([&]() 115 | { 116 | int frameFound = 0,frameNeed = num,timeCount = 0; 117 | 118 | while (1) 119 | { 120 | unique_lock lock_1(Mutex_missionFinish), lock_2(Mutex_imageBuf); 121 | Mat gray; 122 | cvtColor(imageBuf, gray, CV_BGR2GRAY); 123 | patternFind = findChessboardCorners(gray, board_size, corners, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK); 124 | if (patternFind) 125 | { 126 | cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1)); 127 | corners_Seq.push_back(corners); 128 | for (int i = 0; i < corners.size(); i++) 129 | { 130 | char buffer[4]; 131 | sprintf(buffer, "%d", i); 132 | circle(imageBuf, corners[i], 5, Scalar(255,0, 0),2); 133 | putText(imageBuf, buffer, corners[i], 1, 2, Scalar(255, 0, 0), 2); 134 | } 135 | char grayImgName[32]; 136 | sprintf(grayImgName, "imageData/%05d.jpg", frameFound); 137 | imwrite(grayImgName, imageBuf); 138 | 139 | frameFound++; 140 | } 141 | printf("Need: %d, Found: %d, Time: %d Size: %d\n", frameNeed, frameFound, timeCount++, corners.size()); 142 | 143 | if (frameFound == frameNeed) 144 | { 145 | missionFinish = true; 146 | break; 147 | } 148 | 149 | lock_1.unlock(); 150 | lock_2.unlock(); 151 | this_thread::sleep_for(chrono::seconds(2)); 152 | } 153 | }).detach(); 154 | } 155 | 156 | void calibration() 157 | { 158 | vector tempPointSet; 159 | for (int i = 0; i rotation_vectors; /* 每幅图像的旋转向量 */ 175 | vector translation_vectors; /* 每幅图像的平移向量 */ 176 | int flags = 0; 177 | flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC; 178 | flags |= cv::fisheye::CALIB_CHECK_COND; 179 | flags |= cv::fisheye::CALIB_FIX_SKEW; 180 | 181 | /*******由相机的定义使用两个不同的矫正方法*******/ 182 | if(FISH_EYE) 183 | fisheye::calibrate( 184 | object_Points, 185 | corners_Seq, 186 | image_size, 187 | intrinsic_matrix, 188 | distortion_coeffs, 189 | rotation_vectors, 190 | translation_vectors, 191 | flags, cv::TermCriteria(3, 20, 1e-6)); 192 | else 193 | cv::calibrateCamera( 194 | object_Points, 195 | corners_Seq, 196 | image_size, 197 | intrinsic_matrix, 198 | distortion_coeffs, 199 | rotation_vectors, 200 | translation_vectors, 0, cv::TermCriteria(3, 20, 1e-6)); 201 | 202 | Mat R = Mat::eye(3, 3, CV_32F); 203 | Mat newIn; 204 | intrinsic_matrix.copyTo(newIn); 205 | newIn.at(0, 2) = OUTPUT_WIDTH / 2 - WIDTH_ADJUST; 206 | newIn.at(1, 2) = OUTPUT_HEIGTH / 2- HEIGHT_ADJUST; 207 | if (FISH_EYE) 208 | fisheye::initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R, newIn, Size(OUTPUT_WIDTH, OUTPUT_HEIGTH), CV_32FC1, mapx, mapy); 209 | else 210 | initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R, newIn, Size(OUTPUT_WIDTH, OUTPUT_HEIGTH), CV_32FC1, mapx, mapy); 211 | } 212 | 213 | int main() 214 | { 215 | cout << "Calib cam ID is : "; 216 | cin >> camID; 217 | 218 | v.open(0); 219 | 220 | if (!v.isOpened()) return 0; 221 | else 222 | { 223 | v.set(CAP_PROP_FRAME_HEIGHT, CAM_HEIGTH); 224 | v.set(CAP_PROP_FRAME_WIDTH, CAM_WIDTH); 225 | } 226 | 227 | if (!read()) 228 | { 229 | cout << "******* Checking Board Start *******" << endl; 230 | chessCheck(usedImageForCalib); 231 | while (1) 232 | { 233 | unique_lock lock_1(Mutex_missionFinish), lock_2(Mutex_patternFind); 234 | if (missionFinish) break; 235 | } 236 | cout << "******** Checking Board End ********" << endl; 237 | 238 | cout << "********* calibration Start ********" << endl; 239 | calibration(); 240 | cout << "********* calibration Start ********" << endl; 241 | save(); 242 | } 243 | 244 | cout << "********** Display Start ***********" << endl; 245 | missionFinish = false; 246 | display(1); 247 | cout << "************ Display End ***********" << endl; 248 | 249 | waitKey(0); 250 | } 251 | 252 | -------------------------------------------------------------------------------- /img/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linghugoogle/BirdViewTransform/15bdff3acdab9fd971a8e254cc2097be36055a61/img/0.png -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linghugoogle/BirdViewTransform/15bdff3acdab9fd971a8e254cc2097be36055a61/img/1.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linghugoogle/BirdViewTransform/15bdff3acdab9fd971a8e254cc2097be36055a61/img/2.png -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linghugoogle/BirdViewTransform/15bdff3acdab9fd971a8e254cc2097be36055a61/img/3.png -------------------------------------------------------------------------------- /img/ParamSetting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linghugoogle/BirdViewTransform/15bdff3acdab9fd971a8e254cc2097be36055a61/img/ParamSetting.png -------------------------------------------------------------------------------- /img/info.txt: -------------------------------------------------------------------------------- 1 | 0.png: left 2 | 1.png: forward 3 | 2.png: right 4 | 3.png: backward 5 | -------------------------------------------------------------------------------- /img/ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linghugoogle/BirdViewTransform/15bdff3acdab9fd971a8e254cc2097be36055a61/img/ok.png -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "birdView.hpp" 2 | 3 | int main() 4 | { 5 | Mat v[4]; 6 | 7 | for (int i = 0; i < 4; i++) 8 | { 9 | char buf[10]; 10 | sprintf(buf, "%d.png", i); 11 | v[i] = imread(buf); 12 | } 13 | 14 | 15 | BirdView b("config.yml"); 16 | 17 | b.setCarSize(240, 380); 18 | b.setChessSize(60); 19 | b.setMaskHeigth(200); 20 | b.setInternalShift(27,27); 21 | 22 | //b.sourcePointClick(v); 23 | 24 | while (1) 25 | { 26 | imshow("bird view", b.transformView(v)); 27 | if (waitKey(20) == 27) break; 28 | } 29 | } 30 | --------------------------------------------------------------------------------