├── Makefile ├── Model ├── ferns.dat └── normalizedpose.txt ├── RCPR ├── README.md ├── RandomFerns.cpp ├── RandomFerns.h ├── SerializeModel.cpp ├── img.txt ├── img ├── 296814969_3.jpg ├── 2968560214_1.jpg ├── 2968784797_1.jpg └── 296961468_1.jpg ├── opencvseralization.hpp ├── rcpr.cpp └── save_regmodel.m /Makefile: -------------------------------------------------------------------------------- 1 | 2 | OPENCV_PREFIX = /usr/local 3 | BOOST_PREFIX= /usr 4 | INCLUDES = -I$(OPENCV_PREFIX)/include/opencv2 \ 5 | -I$(OPENCV_PREFIX)/include/opencv \ 6 | -I$(BOOST_PREFIX)/include/boost 7 | LIBS = -lopencv_features2d -lopencv_ml -lopencv_highgui -lopencv_imgproc -lopencv_objdetect -lopencv_core \ 8 | -lboost_system -lboost_thread -lboost_serialization -lboost_filesystem 9 | LIBDIRS = -L$(OPENCV_PREFIX)/lib -Wl,-rpath,$(OPENCV_PREFIX)/lib \ 10 | -L$(BOOST_PREFIX)/lib -Wl,-rpath,$(BOOST_PREFIX)/lib \ 11 | -L/usr/lib 12 | CC=g++ 13 | CFLAGS=-c -Wall -O3 14 | SOURCES= RandomFerns.cpp rcpr.cpp 15 | OBJECTS=$(SOURCES:.cpp=.o) 16 | EXECUTABLE=RCPR 17 | 18 | all: $(SOURCES) $(EXECUTABLE) 19 | clean: 20 | rm -f *.o 21 | 22 | $(EXECUTABLE): $(OBJECTS) 23 | $(CC) $(OBJECTS) $(LIBDIRS) $(LIBS) -o $@ 24 | 25 | .cpp.o: 26 | $(CC) $(CFLAGS) $(INCLUDES) $< -o $@ 27 | -------------------------------------------------------------------------------- /Model/ferns.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisYang/RCPR/52f3110623aa1965bd212e7d498d774afa93fcbc/Model/ferns.dat -------------------------------------------------------------------------------- /RCPR: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisYang/RCPR/52f3110623aa1965bd212e7d498d774afa93fcbc/RCPR -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RCPR for RGB and Sketch Face Alignment. 2 | ==== 3 | 4 | C++ code for Robust Cascaded Pose Regression using Random Ferns, traine on both RGB and sketch images. If you use this code please cite my paper as well as the orignal RCPR paper. 5 | 6 | *Heng Yang, C. Zou and Ioannis Patras, "Face sketch landmarks localization in the wild", IEEE Signal Processing Letters, 2014. ** 7 | 8 | If you have any problems running this code, please feel free to contact Heng Yang (yanghengnudt AT gmail.com) 9 | 10 | The original RCPR code was written in matlab which limits its run-time speed performance. I transformed the testing code into C++ and using a python interface. I trained the model fern.dat as described in the above paper. 11 | 12 | Requirements: 13 | --OpenCV 2.4 14 | --boost 1.55 15 | --Tested on Ubuntu 12.04 16 | 17 | ------------------Optional: for creating the model file------------------------------------- 18 | 19 | !!SKIP this step if you do not want to create your own model but only to use the trained model I have created.!! 20 | 21 | Dowload the matlab code from here: http://www.vision.caltech.edu/xpburgos/ICCV13/ 22 | First, I transform the trained model [regModel.mat] into many .txt file (might be not optimal but it works) and store them in a directory called ferns. A cpp program is used to serialize the txt files into a fern class object file, called fern.dat, which is the model file. You can directly use the fern.dat and ignore the following steps. 23 | 24 | 1. load regModel 25 | 26 | 2. mkdir ferns 27 | 28 | 3. run save_regmodel in matlab (it takes a few minutes) 29 | 30 | 4. make -f Makefile_Serialize 31 | 32 | 5. $./RCPRSerializer 33 | 34 | ----------------------------------------------------------------------------------- 35 | 36 | ----------------------------------------------------------------------------------- 37 | ###For running the model. 38 | 39 | $ make 40 | 41 | RCPR will be created 42 | 43 | Then run 44 | 45 | $./RCRP Model/fern.dat yourfilelist.txt 46 | 47 | e.g.: ./RCPR Model/fern.dat img.txt 48 | 49 | it will save the result to result_img.txt when it finishes 50 | 51 | ###FAQs 52 | #####Q: Why do i get error when loading the model in Windows? 53 | #####A: The binary model is created in Ubuntu, and it is not made compatiable to Windows os. I have a version of txt files. If you do need it, please email me. 54 | 55 | -------------------------------------------------------------------------------- /RandomFerns.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * RandomFerns.cpp 3 | * 4 | * Created on: 15 Mar 2014 5 | * Author: hy 6 | */ 7 | 8 | #include "RandomFerns.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace cv; 14 | using namespace std; 15 | void reprojectpose(cv::Mat pose1, cv::Mat& pose2, cv::Rect bbox){ 16 | float sx = bbox.width/2.0; 17 | float sy = bbox.height/2.0; 18 | float ctrx = bbox.x + sx; 19 | float ctry = bbox.y + sy; 20 | pose2 = pose1.clone(); 21 | int nc = pose1.cols; 22 | pose2.colRange(0,nc/2) *= sx; 23 | pose2.colRange(0,nc/2) += ctrx; 24 | pose2.colRange(nc/2,nc) *= sy; 25 | pose2.colRange(nc/2,nc) += ctry; 26 | } 27 | void projectpose(cv::Mat pose1, cv::Mat& pose2, cv::Rect bbox){ 28 | float sx = bbox.width/2.0; 29 | float sy = bbox.height/2.0; 30 | float ctrx = bbox.x + sx; 31 | float ctry = bbox.y + sy; 32 | pose2 = pose1.clone(); 33 | int nc = pose1.cols; 34 | pose2.colRange(0,nc/2) -= ctrx; 35 | pose2.colRange(0,nc/2) /= sx; 36 | pose2.colRange(nc/2,nc) -= ctry; 37 | pose2.colRange(nc/2,nc) /= sy; 38 | } 39 | int calculate_fernid(cv::Mat feats,std::vector fernfuncs){ 40 | int id = 0; 41 | for(int k = 0; k< fernfuncs.size(); k++){ 42 | id *= 2; 43 | float dif = feats.at(fernfuncs[k].id1-1,0) - feats.at(fernfuncs[k].id2-1,0); 44 | if(dif < fernfuncs[k].t1) 45 | id += 1; 46 | } 47 | return id; 48 | } 49 | RandomFerns::RandomFerns() { 50 | // TODO Auto-generated constructor stub 51 | depth = 5; 52 | num_leafs = 32; 53 | posdim = 136; 54 | num_levels = 100; 55 | num_ferns_pl = 50; 56 | num_fea_locs = 400; 57 | allferns.resize(num_levels); 58 | } 59 | 60 | bool RandomFerns::Load_Ferns(std::string filename) { 61 | 62 | for (unsigned int k = 0; k < num_levels; k++){ 63 | std::cout << k << std::endl; 64 | allferns[k].ferns.resize(num_ferns_pl); 65 | allferns[k].line_pids.resize(num_fea_locs); 66 | char c[10]; 67 | sprintf(c,"%d",k); 68 | std::string file_name = filename +c+".txt"; 69 | ifstream filereader; 70 | filereader.open(file_name.c_str()); 71 | for (unsigned int f =0; f < num_fea_locs; f++){ 72 | filereader >> allferns[k].line_pids[f].id1; 73 | filereader >> allferns[k].line_pids[f].id2; 74 | filereader >> allferns[k].line_pids[f].t1; 75 | } 76 | for (unsigned int n=0; n < num_ferns_pl; n++){ 77 | allferns[k].ferns[n].fernfuncs.resize(depth); 78 | allferns[k].ferns[n].leafVecs = cv::Mat(num_leafs,posdim,CV_32FC1); 79 | for (unsigned int r = 0; r < num_leafs; r++) 80 | for (unsigned int c =0; c < posdim; c++){ 81 | filereader >> allferns[k].ferns[n].leafVecs.at(r,c); 82 | } 83 | for(unsigned int d = 0; d < depth; d++){ 84 | filereader >> allferns[k].ferns[n].fernfuncs[d].id1; 85 | filereader >> allferns[k].ferns[n].fernfuncs[d].id2; 86 | filereader >> allferns[k].ferns[n].fernfuncs[d].t1; 87 | } 88 | } 89 | filereader.close(); 90 | } 91 | return true; 92 | } 93 | 94 | bool RandomFerns::Apply_Ferns(cv::Mat img,cv::Rect bbox, cv::Mat& init_pose){ 95 | //convert image into double with range [0,1] 96 | cv::Mat initpose2; 97 | reprojectpose(init_pose,initpose2,bbox); 98 | // cv::Mat temp; 99 | // img.convertTo(temp,CV_8UC1,255.); 100 | // for (int p = 0; p < 136/2; p++){ 101 | // int x = init_pose.at(0,p); 102 | // int y = init_pose.at(0,p+68); 103 | // cv::circle(temp, cv::Point_(x,y),2, cv::Scalar(0, 0, 255, 0),2); 104 | // } 105 | // cv::imshow("tmp",temp); 106 | // cv::waitKey(0); 107 | // cv:: destroyAllWindows(); 108 | for (int t = 0; t < allferns.size(); t++){ 109 | cv::Mat feats; 110 | get_linepoint(img,initpose2,allferns[t].line_pids,feats); 111 | cv::Mat pDel = cv::Mat(1,posdim,CV_32FC1); 112 | pDel.setTo(0.0); 113 | cv::Mat posetmp; 114 | projectpose(initpose2, posetmp,bbox); 115 | for (int k = 0; k < allferns[t].ferns.size(); k++){ 116 | int id = calculate_fernid(feats,allferns[t].ferns[k].fernfuncs); 117 | pDel += allferns[t].ferns[k].leafVecs.row(id); 118 | } 119 | posetmp += pDel; 120 | reprojectpose(posetmp,initpose2,bbox); 121 | posetmp.release(); 122 | } 123 | init_pose = initpose2.clone(); 124 | 125 | } 126 | void RandomFerns::get_linepoint(cv::Mat img,cv::Mat init_pose,std::vector line_pids, cv::Mat& feats){ 127 | int cs = init_pose.cols; 128 | int w = img.cols; 129 | int h = img.rows; 130 | assert(cs==posdim); 131 | assert(line_pids.size()==num_fea_locs); 132 | feats = cv::Mat(num_fea_locs,1,CV_32FC1); 133 | cv::Mat xs = init_pose.colRange(0,cs/2).clone(); 134 | cv::Mat ys = init_pose.colRange(cs/2,cs).clone(); 135 | float mx = cv::mean(xs).val[0]; 136 | float my = cv::mean(ys).val[0]; 137 | xs -= mx; 138 | ys -= my; 139 | for (int k =0; k < line_pids.size(); k++){ 140 | float p1x = xs.at(0,line_pids[k].id1-1); 141 | float p1y = ys.at(0,line_pids[k].id1-1); 142 | float p2x = xs.at(0,line_pids[k].id2-1); 143 | float p2y = ys.at(0,line_pids[k].id2-1); 144 | float a = (p2y-p1y)/(p2x-p1x); 145 | float b = p1y - a*p1x; 146 | float distx = (p2x-p1x)/2; 147 | float ctrx = p1x + distx; 148 | float cs1 = ctrx+line_pids[k].t1*distx; 149 | float rs1 = a*cs1+b; 150 | int cs = (int)(cs1+mx); 151 | int rs = (int)(rs1+my); 152 | // std::cout<< rs << " " << cs << std::endl; 153 | feats.at(k,0) = img.at(max(0,min(h-1,rs)),max(0,min(w-1,cs))); 154 | // std::cout << feats.at(k,0) << std::endl; 155 | } 156 | 157 | } 158 | 159 | 160 | RandomFerns::~RandomFerns() { 161 | // TODO Auto-generated destructor stub 162 | } 163 | 164 | -------------------------------------------------------------------------------- /RandomFerns.h: -------------------------------------------------------------------------------- 1 | /* 2 | * RandomFerns.h 3 | * 4 | * Created on: 15 Mar 2014 5 | * Author: hy 6 | */ 7 | #include "opencv2/opencv.hpp" 8 | #include 9 | #include 10 | #include 11 | 12 | #include "opencvseralization.hpp" 13 | 14 | #ifndef RANDOMFERNS_H_ 15 | #define RANDOMFERNS_H_ 16 | 17 | struct l1l2f1{//define one point on a line given two points and the ratio 18 | int id1; 19 | int id2; 20 | float t1; 21 | friend class boost::serialization::access; 22 | template 23 | void serialize(Archive & ar, const unsigned int version) { 24 | ar & id1; 25 | ar & id2; 26 | ar & t1; 27 | } 28 | }; 29 | struct fern{ 30 | std::vector fernfuncs; 31 | cv::Mat leafVecs; 32 | friend class boost::serialization::access; 33 | template 34 | void serialize(Archive & ar, const unsigned int version) { 35 | ar & fernfuncs; 36 | ar & leafVecs; 37 | } 38 | }; 39 | 40 | struct fernlevel{ 41 | int num_ferns; 42 | int num_locs; 43 | std::vector line_pids; 44 | std::vector ferns; 45 | friend class boost::serialization::access; 46 | template 47 | void serialize(Archive & ar, const unsigned int version) { 48 | ar & num_ferns; 49 | ar & num_locs; 50 | ar & line_pids; 51 | ar & ferns; 52 | } 53 | }; 54 | class RandomFerns { 55 | public: 56 | RandomFerns(); 57 | bool Load_Ferns(std::string filename); 58 | bool Apply_Ferns(cv::Mat img, cv::Rect bbox, cv::Mat& init_pose); 59 | void get_linepoint(cv::Mat img,cv::Mat init_pose,std::vector line_pids, cv::Mat& locs); 60 | virtual ~RandomFerns(); 61 | 62 | public: 63 | int depth; 64 | int num_leafs; 65 | int posdim; 66 | int num_levels; 67 | int num_ferns_pl; 68 | int num_fea_locs; // for each image, 400 locations 69 | std::vector allferns; 70 | private: 71 | friend class boost::serialization::access; 72 | template 73 | void serialize(Archive & ar, const unsigned int version) 74 | { 75 | ar & depth; 76 | ar & num_leafs; 77 | ar & posdim; 78 | ar & num_levels; 79 | ar & num_ferns_pl; 80 | ar & num_fea_locs; 81 | ar & allferns; 82 | } 83 | }; 84 | 85 | #endif /* RANDOMFERNS_H_ */ 86 | -------------------------------------------------------------------------------- /SerializeModel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "RandomFerns.h" 3 | #include 4 | #include 5 | #include 6 | using namespace cv; 7 | using namespace std; 8 | 9 | 10 | int main( int argc, char** argv ) 11 | { 12 | // cv::Mat trainposes; 13 | // cv::Rect facebb; 14 | //// int key = 0; 15 | //// string winname("CoolFace"); 16 | // std::string videoname = argv[1]; 17 | // std::string filename = videoname+".txt"; 18 | // ofstream file(filename.c_str()); 19 | //// std::string imgname("photos/test.jpg"); 20 | // load_trainposes(trainposes,"Model/normalizedpose.txt"); 21 | // string faceDetectionModel("Model/haarcascade_frontalface_alt2.xml"); 22 | RandomFerns ferns; 23 | 24 | // Loading model from text file 25 | if(!ferns.Load_Ferns("./ferns/ferns_level")) 26 | std::cout <<"Ferns loading fails" << std::endl; 27 | std::ofstream ofs("ferns.dat", std::ios::binary);//save to binary file 28 | boost::archive::binary_oarchive oa(ofs); 29 | oa << ferns; 30 | std::ifstream ifs("ferns.dat"); 31 | if (!ifs) { 32 | std::cout << "Model not found " << std::endl; 33 | return false; 34 | } 35 | //load model 36 | try { 37 | boost::archive::binary_iarchive ia(ifs); 38 | ia >> ferns; 39 | } catch (boost::archive::archive_exception& ex) { 40 | std::cout << "Archive Exception during deserializing:" << std::endl; 41 | std::cout << ex.what() << std::endl; 42 | } catch (int e) { 43 | std::cout << "EXCEPTION " << e << std::endl; 44 | 45 | } 46 | ifs.close(); 47 | std::cout << ferns.depth << std::endl; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /img.txt: -------------------------------------------------------------------------------- 1 | img/296814969_3.jpg 285.0 211.0 327.0 327.0 265.309 352.5 270.507 392.107 281.902 427.599 294.249 463.744 315.26 497.968 344.615 526.42 381.787 550.86 421.189 562.345 460.5 560.345 489.411 549.469 512.239 523.29 532.004 494.988 553.406 461.814 564.656 427.29 565.489 392.534 562.441 359.855 562.479 326.126 331.477 327.009 351.221 311.113 374.583 304.234 399.58 305.476 423.037 310.314 472.59 313.132 492.608 301.751 512.514 291.52 534.64 292.332 552.747 302.828 457.0 344.286 461.059 366.893 465.739 388.873 470.552 411.869 435.162 437.088 451.645 438.139 468.721 439.129 480.731 433.96 491.605 427.799 362.917 349.679 378.88 339.043 397.678 338.175 412.766 352.712 397.864 357.595 378.806 357.198 485.475 343.482 498.084 327.375 513.522 324.898 525.759 330.523 514.324 340.552 498.421 343.725 402.828 474.595 432.44 467.056 455.9 460.729 465.709 461.505 474.093 457.97 490.844 458.733 504.603 459.134 492.789 483.659 478.29 493.81 468.31 496.738 456.876 497.486 433.458 495.735 410.454 476.467 456.625 472.053 466.42 470.903 474.853 468.921 498.225 463.742 475.647 477.641 466.834 480.924 456.841 481.113 2 | img/2968560214_1.jpg 48.0 207.0 590.0 590.0 135.607 318.032 130.156 390.964 128.464 467.468 130.25 544.536 144.63 617.657 173.766 690.872 216.341 754.5 256.567 812.582 322.826 851.961 415.401 849.799 494.536 814.179 556.848 765.964 614.179 710.607 653.935 640.024 680.062 565.87 682.0 479.78 682.0 401.02 140.402 331.453 174.33 301.662 218.565 296.916 259.887 312.393 295.099 342.656 447.48 355.974 495.284 345.899 541.194 341.278 584.474 365.772 615.052 396.443 359.557 430.166 350.207 491.194 338.647 552.331 329.092 611.368 282.036 617.955 302.21 632.554 324.893 646.321 355.25 639.179 382.458 632.663 192.906 385.841 228.777 375.535 264.179 387.393 285.701 423.013 253.464 421.321 213.647 412.393 448.765 445.57 481.002 422.073 524.047 427.43 549.579 449.048 519.536 457.458 478.996 455.484 242.436 684.213 269.536 683.821 305.359 681.3 319.975 692.75 337.004 688.443 394.362 701.773 463.347 708.837 394.331 765.228 331.884 772.904 310.108 769.521 292.859 761.61 264.774 740.807 255.642 694.427 300.519 713.035 317.641 722.481 333.434 720.79 439.191 717.014 334.17 729.623 317.641 722.481 300.519 713.035 3 | img/2968784797_1.jpg 604.0 512.0 2181.0 2181.0 351.246 1496.715 408.352 1741.311 479.109 1998.117 537.082 2248.566 652.711 2505.577 823.562 2734.681 1062.827 2847.0 1344.073 2847.0 1655.466 2847.0 1928.553 2847.0 2122.121 2793.235 2285.15 2572.45 2395.451 2362.641 2446.974 2106.024 2461.063 1849.477 2472.876 1525.476 2507.882 1203.369 595.13 1370.383 727.629 1182.09 950.034 1105.483 1198.596 1148.452 1439.106 1200.739 1776.005 1178.055 1959.728 1107.95 2133.522 1051.036 2310.53 1051.624 2437.195 1195.918 1628.615 1388.684 1638.761 1567.906 1646.004 1749.15 1666.795 1942.893 1432.671 2111.754 1528.965 2130.539 1636.664 2149.957 1714.513 2109.597 1775.432 2073.181 868.649 1505.779 1011.568 1408.777 1168.422 1391.389 1319.064 1521.381 1157.987 1567.392 1002.822 1574.306 1859.254 1481.314 1993.527 1335.378 2142.691 1326.496 2227.223 1411.82 2174.068 1485.064 2019.391 1507.921 1236.533 2451.232 1381.969 2406.303 1510.593 2373.87 1625.139 2388.493 1744.059 2360.258 1842.615 2382.525 1944.701 2387.999 1847.921 2523.251 1754.673 2581.636 1635.377 2617.095 1502.719 2609.328 1376.561 2558.988 1272.585 2457.829 1509.991 2466.371 1629.642 2466.127 1748.354 2444.63 1899.534 2406.352 1748.354 2444.63 1629.642 2466.127 1509.991 2466.371 4 | img/296961468_1.jpg 872.0 821.0 1227.0 1227.0 799.344 1294.306 820.714 1447.665 840.682 1591.288 882.528 1741.024 941.856 1884.532 1051.788 2001.649 1176.875 2089.523 1326.517 2158.906 1491.736 2192.526 1625.224 2139.802 1719.694 2055.21 1802.766 1955.248 1856.275 1833.757 1891.626 1698.706 1918.518 1562.864 1935.998 1427.153 1945.75 1280.073 1012.443 1167.077 1108.292 1119.512 1208.98 1108.155 1313.147 1118.114 1417.968 1142.255 1628.545 1141.27 1706.356 1122.052 1783.129 1113.596 1868.172 1113.887 1907.724 1175.206 1544.015 1261.931 1555.895 1343.26 1570.034 1430.0 1586.036 1518.995 1445.363 1613.188 1510.069 1631.984 1558.522 1648.124 1601.972 1629.602 1635.558 1612.496 1141.051 1287.247 1226.242 1242.648 1308.022 1240.616 1364.036 1297.833 1300.694 1317.177 1220.658 1326.141 1620.337 1300.489 1698.032 1237.09 1773.918 1233.164 1829.178 1282.048 1785.546 1311.206 1708.567 1316.788 1313.082 1831.283 1395.307 1773.236 1482.811 1747.98 1536.655 1764.21 1585.216 1749.792 1641.978 1773.79 1683.377 1823.525 1638.207 1906.038 1586.903 1937.651 1534.734 1946.852 1478.936 1943.455 1392.1 1895.903 1356.411 1832.074 1484.56 1803.916 1534.855 1803.195 1585.026 1804.147 1639.41 1829.197 1586.425 1851.68 1533.592 1857.581 1483.373 1858.765 5 | -------------------------------------------------------------------------------- /img/296814969_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisYang/RCPR/52f3110623aa1965bd212e7d498d774afa93fcbc/img/296814969_3.jpg -------------------------------------------------------------------------------- /img/2968560214_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisYang/RCPR/52f3110623aa1965bd212e7d498d774afa93fcbc/img/2968560214_1.jpg -------------------------------------------------------------------------------- /img/2968784797_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisYang/RCPR/52f3110623aa1965bd212e7d498d774afa93fcbc/img/2968784797_1.jpg -------------------------------------------------------------------------------- /img/296961468_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisYang/RCPR/52f3110623aa1965bd212e7d498d774afa93fcbc/img/296961468_1.jpg -------------------------------------------------------------------------------- /opencvseralization.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * serialize_helper.hpp 3 | * 4 | * Created on: Oct 12, 2011 5 | * Author: Lukas Bossard, Matthias Dantone 6 | */ 7 | 8 | #ifndef UTILS_OPENCV_SERIALIZATION_HPP_ 9 | #define UTILS_OPENCV_SERIALIZATION_HPP_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace boost { 16 | namespace serialization { 17 | 18 | template 19 | void save(Archive & ar, const cv::Mat& mat_, const unsigned int version) { 20 | cv::Mat mat = mat_; 21 | if (!mat_.isContinuous()) { 22 | mat = mat_.clone(); 23 | } 24 | 25 | int elem_type = mat.type(); 26 | std::size_t elem_size = mat.elemSize(); 27 | ar & mat.rows; 28 | ar & mat.cols; 29 | ar & elem_type; 30 | ar & elem_size; 31 | ar & boost::serialization::make_binary_object(mat.data, mat.step * mat.rows); 32 | } 33 | template 34 | void load(Archive & ar, cv::Mat& mat, const unsigned int version) { 35 | int rows, cols, elem_type; 36 | std::size_t elem_size; 37 | ar & rows; 38 | ar & cols; 39 | ar & elem_type; 40 | ar & elem_size; 41 | mat.create(rows, cols, elem_type); 42 | ar & boost::serialization::make_binary_object(mat.data, mat.step * mat.rows); 43 | } 44 | 45 | template 46 | void save(Archive & ar, const cv::Mat_& mat_, const unsigned int version) { 47 | save(ar, static_cast(mat_), version); 48 | } 49 | 50 | template 51 | void load(Archive & ar, cv::Mat_& mat_, const unsigned int version) { 52 | load(ar, static_cast(mat_), version); 53 | 54 | if (static_cast(mat_).type() != cv::DataType::type) { 55 | mat_.create(0, 0); 56 | } 57 | } 58 | 59 | // ------------- cv::Rect_ 60 | template 61 | void serialize(Archive & ar, cv::Rect_& rect, const unsigned int version) { 62 | ar & rect.x; 63 | ar & rect.y; 64 | ar & rect.width; 65 | ar & rect.height; 66 | } 67 | 68 | // ------------- cv::Point_ 69 | template 70 | void serialize(Archive & ar, cv::Point_& point, const unsigned int version) { 71 | ar & point.x; 72 | ar & point.y; 73 | } 74 | 75 | } 76 | } 77 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat); 78 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat_); 79 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat_); 80 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat_); 81 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat_); 82 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat_); 83 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat_); 84 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat_); 85 | BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat_); 86 | 87 | #endif /* UTILS_OPENCV_SERIALIZATION_HPP_ */ 88 | -------------------------------------------------------------------------------- /rcpr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * rcpr.cpp 3 | * 4 | * Created on: 13 Apr 2014 5 | * Author: hy300@eecs.qmul.ac.uk 6 | */ 7 | 8 | 9 | 10 | 11 | #include 12 | #include "RandomFerns.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | using namespace cv; 22 | using namespace std; 23 | 24 | bool compareRect(cv::Rect r1, cv::Rect r2) { return r1.height < r2.height; } 25 | 26 | bool load_annotations(std::vector& names, std::vector& rects, std::string url) { 27 | if (boost::filesystem::exists(url.c_str())) { 28 | std::string filename(url.c_str()); 29 | boost::iostreams::stream < boost::iostreams::file_source > file( 30 | filename.c_str()); 31 | std::string line; 32 | names.clear(); 33 | rects.clear(); 34 | while (std::getline(file, line)) { 35 | std::vector < std::string > strs; 36 | boost::split(strs, line, boost::is_any_of(" ")); 37 | names.push_back(strs[0]); 38 | cv::Rect rect; 39 | rect.x = std::atoi(strs[1].c_str()); 40 | rect.y = std::atoi(strs[2].c_str()); 41 | rect.width = std::atoi(strs[3].c_str()); 42 | rect.height = std::atoi(strs[4].c_str()); 43 | rects.push_back(rect); 44 | } 45 | return true; 46 | } 47 | return false; 48 | } 49 | void load_trainposes(cv::Mat& train_poses,std::string filename){ 50 | ifstream filereader; 51 | filereader.open(filename.c_str(),std::ifstream::in); 52 | train_poses = cv::Mat(300,136,CV_32FC1); 53 | if (filereader.is_open()){ 54 | for (int k1 = 0; k1< 300; k1++) 55 | for (int k2 =0; k2< 136; k2++){ 56 | float a = 0; 57 | filereader >> a; 58 | // std::cout << a; 59 | train_poses.at(k1,k2) = a; 60 | } 61 | filereader.close(); 62 | } 63 | } 64 | float CalcMedianValue(vector scores) 65 | { 66 | float median; 67 | size_t size = scores.size(); 68 | sort(scores.begin(), scores.end()); 69 | 70 | if (size % 2 == 0) 71 | { 72 | median = (scores[size / 2 - 1] + scores[size / 2]) / 2; 73 | } 74 | else 75 | { 76 | median = scores[size / 2]; 77 | } 78 | 79 | return median; 80 | } 81 | int main( int argc, char** argv ) 82 | { 83 | cv::Mat trainposes; 84 | cv::Rect facebb; 85 | int key = 0; 86 | int num_inits = 7; 87 | string winname("RCPR"); 88 | cv::namedWindow(winname,false); 89 | if (argc > 3) 90 | num_inits = atoi(argv[3]); 91 | // std::cout << num_inits << std::endl; 92 | std::string imgsfilename = argv[2]; 93 | std::string modelname = argv[1]; 94 | //std::string path = argv[2]; 95 | std::string filename = "result_"+imgsfilename; 96 | ofstream file(filename.c_str()); 97 | std::vector names; 98 | std::vector rects; 99 | 100 | load_annotations(names,rects,imgsfilename); 101 | std::cout << "here" << std::endl; 102 | // std::string imgname("photos/test.jpg"); 103 | load_trainposes(trainposes,"Model/normalizedpose.txt"); 104 | // string faceDetectionModel("Model/haarcascade_frontalface_alt2.xml"); 105 | RandomFerns ferns; 106 | std::ifstream ifs(modelname.c_str()); 107 | if (!ifs) { 108 | std::cout << "Model not found " << std::endl; 109 | return false; 110 | } 111 | //load model 112 | try { 113 | boost::archive::binary_iarchive ia(ifs); 114 | ia >> ferns; 115 | } catch (boost::archive::archive_exception& ex) { 116 | std::cout << "Archive Exception during deserializing:" << std::endl; 117 | std::cout << ex.what() << std::endl; 118 | } catch (int e) { 119 | std::cout << "EXCEPTION " << e << std::endl; 120 | 121 | } 122 | ifs.close(); 123 | std::cout << ferns.depth << std::endl; 124 | int framenum = 0; 125 | 126 | for (int k = 0; k < names.size(); k++) 127 | { 128 | std::cout << names[k] << std::endl; 129 | cv::Mat frame = cv::imread(names[k]); 130 | if(frame.empty()) 131 | break; 132 | cv::Mat gray; 133 | cv::Mat gray_float; 134 | cv::cvtColor(frame,gray,CV_BGR2GRAY); 135 | framenum ++; 136 | 137 | std::cout << framenum << std::endl; 138 | if(!frame.empty()){ 139 | gray.convertTo(gray_float,CV_32FC1,1./255.); 140 | facebb = rects[k]; 141 | cv::rectangle(frame,cv::Point(facebb.x, facebb.y), cv::Point(facebb.x+facebb.width,facebb.y+facebb.height), cv::Scalar(255,0,0)); 142 | std::vector inits; 143 | inits.clear(); 144 | for (int ii = 0; ii< num_inits; ii++) 145 | inits.push_back(trainposes.row(ii).clone()); 146 | for (int n_i = 0; n_i < num_inits; n_i++) 147 | ferns.Apply_Ferns(gray_float,facebb,inits[n_i]); 148 | for (int p = 0; p < 136/2; p++){ 149 | std::vector xs;std::vector ys; 150 | for (int ii=0; ii< num_inits; ii++){ 151 | xs.push_back(inits[ii].at(0,p));// xs.push_back(inits[1].at(0,p));xs.push_back(inits[2].at(0,p)); 152 | ys.push_back(inits[ii].at(0,p+68));// ys.push_back(inits[1].at(0,p+68));ys.push_back(inits[2].at(0,p+68)); 153 | } 154 | float x = CalcMedianValue(xs); 155 | float y = CalcMedianValue(ys); 156 | file << x <<" " << y << " "; 157 | cv::circle(frame, cv::Point_(x,y),int(1./150.*facebb.width)+1, cv::Scalar(0, 0, 255, 0),int(1./150.*facebb.width)+1); 158 | } 159 | 160 | 161 | cv::imshow(winname,frame); 162 | key = cv::waitKey(1); 163 | file <