Commit ccb584504f71c79bb2b8a31f32610ca0287ac03e

Authored by Josh Klontz
2 parents 559d0193 1af9c6ce

Merge pull request #423 from biometrics/openbr_1_0

Openbr 1 0
docs/docs/install.md
@@ -35,7 +35,7 @@ A hacker's guide to building, editing, and running OpenBR. @@ -35,7 +35,7 @@ A hacker's guide to building, editing, and running OpenBR.
35 35
36 $ git clone https://github.com/biometrics/openbr.git 36 $ git clone https://github.com/biometrics/openbr.git
37 $ cd openbr 37 $ cd openbr
38 - $ git checkout 0.5 38 + $ git checkout 1.0
39 $ git submodule init 39 $ git submodule init
40 $ git submodule update 40 $ git submodule update
41 41
@@ -71,8 +71,14 @@ A hacker's guide to building, editing, and running OpenBR. @@ -71,8 +71,14 @@ A hacker's guide to building, editing, and running OpenBR.
71 $ sudo cpack -G TGZ 71 $ sudo cpack -G TGZ
72 72
73 10. (Optional) Build OpenBR documentation! 73 10. (Optional) Build OpenBR documentation!
  74 + 1. Build the docs
74 75
75 -Need to rewrite this step for the new docs! 76 + $ pip install mkdocs
  77 + $ cd openbr/docs
  78 + $ sh build_docs.sh
  79 + $ mkdocs serve
  80 +
  81 + 2. Navigate to `http://127.0.0.1:8000` in your browser to view the docs.
76 82
77 --- 83 ---
78 84
@@ -83,13 +89,13 @@ Need to rewrite this step for the new docs! @@ -83,13 +89,13 @@ Need to rewrite this step for the new docs!
83 2. [Download CMake 3.0.2](http://www.cmake.org/files/v3.0/cmake-3.0.2.tar.gz) 89 2. [Download CMake 3.0.2](http://www.cmake.org/files/v3.0/cmake-3.0.2.tar.gz)
84 90
85 $ cd ~/Downloads 91 $ cd ~/Downloads
86 - $ tar -xf cmake-2.8.11.2.tar.gz  
87 - $ cd cmake-2.8.11.2 92 + $ tar -xf cmake-3.0.2.tar.gz
  93 + $ cd cmake-3.0.2
88 $ ./configure 94 $ ./configure
89 $ make -j4 95 $ make -j4
90 $ sudo make install 96 $ sudo make install
91 $ cd .. 97 $ cd ..
92 - $ rm -rf cmake-2.8.11.2* 98 + $ rm -rf cmake-3.0.2*
93 99
94 3. [Download OpenCV 2.4.11](http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.11/opencv-2.4.11.zip/download) 100 3. [Download OpenCV 2.4.11](http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.11/opencv-2.4.11.zip/download)
95 101
@@ -110,7 +116,7 @@ Need to rewrite this step for the new docs! @@ -110,7 +116,7 @@ Need to rewrite this step for the new docs!
110 116
111 $ git clone https://github.com/biometrics/openbr.git 117 $ git clone https://github.com/biometrics/openbr.git
112 $ cd openbr 118 $ cd openbr
113 - $ git checkout 0.5 119 + $ git checkout 1.0
114 $ git submodule init 120 $ git submodule init
115 $ git submodule update 121 $ git submodule update
116 122
@@ -148,8 +154,14 @@ Need to rewrite this step for the new docs! @@ -148,8 +154,14 @@ Need to rewrite this step for the new docs!
148 154
149 155
150 10. (Optional) Build OpenBR documentation! 156 10. (Optional) Build OpenBR documentation!
  157 + 1. Build the docs
  158 +
  159 + $ pip install mkdocs
  160 + $ cd openbr/docs
  161 + $ sh build_docs.sh
  162 + $ mkdocs serve
151 163
152 -Need to remake this step with the new docs! 164 + 2. Navigate to `http://127.0.0.1:8000` in your browser to view the docs.
153 165
154 --- 166 ---
155 167
@@ -184,7 +196,7 @@ Need to remake this step with the new docs! @@ -184,7 +196,7 @@ Need to remake this step with the new docs!
184 $ cd /c 196 $ cd /c
185 $ git clone https://github.com/biometrics/openbr.git 197 $ git clone https://github.com/biometrics/openbr.git
186 $ cd openbr 198 $ cd openbr
187 - $ git checkout 0.5 199 + $ git checkout 1.0
188 $ git submodule init 200 $ git submodule init
189 $ git submodule update 201 $ git submodule update
190 202
@@ -265,7 +277,7 @@ Need to remake this step with the new docs! @@ -265,7 +277,7 @@ Need to remake this step with the new docs!
265 277
266 $ git clone https://github.com/biometrics/openbr.git 278 $ git clone https://github.com/biometrics/openbr.git
267 $ cd openbr 279 $ cd openbr
268 - $ git checkout 0.5 280 + $ git checkout 1.0
269 $ git submodule init 281 $ git submodule init
270 $ git submodule update 282 $ git submodule update
271 283
openbr/plugins/cmake/dlib.cmake
1 -set(BR_WITH_DLIB ON CACHE BOOL "Build with DLib") 1 +set(BR_WITH_DLIB OFF CACHE BOOL "Build with DLib")
2 2
3 if(${BR_WITH_DLIB}) 3 if(${BR_WITH_DLIB})
4 ExternalProject_Add(dlib 4 ExternalProject_Add(dlib
5 - URL https://github.com/davisking/dlib/releases/download/v18.16/dlib-18.16.tar.bz2 5 + URL http://downloads.sourceforge.net/project/dclib/dlib/v18.16/dlib-18.16.tar.bz2
6 URL_MD5 e9e5449bc25370afce2d254327afac99 6 URL_MD5 e9e5449bc25370afce2d254327afac99
7 SOURCE_DIR "${PROJECT_SOURCE_DIR}/3rdparty/dlib-18.16" 7 SOURCE_DIR "${PROJECT_SOURCE_DIR}/3rdparty/dlib-18.16"
8 CONFIGURE_COMMAND "" 8 CONFIGURE_COMMAND ""
openbr/plugins/core/algorithms.cpp
@@ -31,20 +31,29 @@ class AlgorithmsInitializer : public Initializer @@ -31,20 +31,29 @@ class AlgorithmsInitializer : public Initializer
31 void initialize() const 31 void initialize() const
32 { 32 {
33 // Face 33 // Face
34 - Globals->abbreviations.insert("FaceRecognition", "FaceDetection+FaceRecognitionRegistration+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>+SetMetadata(AlgorithmID,-1):Unit(ByteL1)"); 34 + Globals->abbreviations.insert("FaceRecognition", "FaceRecognition_1_0");
  35 +
  36 + Globals->abbreviations.insert("FaceRecognition_1_0", "FR_Detect+(FR_Eyes+FR_Represent)/(FR_Eyebrows+FR_Represent)/(FR_Mouth+FR_Represent)/(FR_Nose+FR_Represent)/(FR_Face+FR_Represent+ScaleMat(2.0))+Cat+LDA(768)+Normalize(L2):Dist(L2)");
  37 + Globals->abbreviations.insert("FR_Eyes", "(CropFromLandmarks([30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47],paddingVertical=.8,paddingHorizontal=.2)+Resize(24,48))");
  38 + Globals->abbreviations.insert("FR_Eyebrows", "(CropFromLandmarks([16,17,18,19,20,21,22,23,24,25,26,27],paddingVertical=.8,paddingHorizontal=.2)+Resize(24,48))");
  39 + Globals->abbreviations.insert("FR_Mouth", "(CropFromLandmarks([59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76])+Resize(24,48))");
  40 + Globals->abbreviations.insert("FR_Nose", "(CropFromLandmarks([16,17,18,19,20,21,22,23,24,25,26,27],padding=3)+Resize(36,36))");
  41 + Globals->abbreviations.insert("FR_Face", "(Crop(24,24,88,88)+Resize(44,44))");
  42 + Globals->abbreviations.insert("FR_Detect", "(FaceDetection+Stasm+Rename(StasmLeftEye,Affine_1,true)+Rename(StasmRightEye,Affine_0,true)+Affine(136,136,0.35,0.35,warpPoints=true))");
  43 + Globals->abbreviations.insert("FR_Represent", "((DenseHOG/DenseLBP)+Cat+LDA(.98)+Normalize(L2))");
  44 +
35 Globals->abbreviations.insert("GenderClassification", "FaceDetection+Expand+FaceClassificationRegistration+Expand+<FaceClassificationExtraction>+<GenderClassifier>+Discard"); 45 Globals->abbreviations.insert("GenderClassification", "FaceDetection+Expand+FaceClassificationRegistration+Expand+<FaceClassificationExtraction>+<GenderClassifier>+Discard");
36 Globals->abbreviations.insert("AgeRegression", "FaceDetection+Expand+FaceClassificationRegistration+Expand+<FaceClassificationExtraction>+<AgeRegressor>+Discard"); 46 Globals->abbreviations.insert("AgeRegression", "FaceDetection+Expand+FaceClassificationRegistration+Expand+<FaceClassificationExtraction>+<AgeRegressor>+Discard");
  47 + Globals->abbreviations.insert("FaceQuality", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+ImageQuality+Cvt(Gray)+DFFS+Discard");
37 Globals->abbreviations.insert("MedianFace", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(256,256,0.37,0.45)+Center(Median)"); 48 Globals->abbreviations.insert("MedianFace", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(256,256,0.37,0.45)+Center(Median)");
38 Globals->abbreviations.insert("BlurredFaceDetection", "Open+LimitSize(1024)+SkinMask/(Cvt(Gray)+GradientMask)+And+Morph(Erode,16)+LargestConvexArea"); 49 Globals->abbreviations.insert("BlurredFaceDetection", "Open+LimitSize(1024)+SkinMask/(Cvt(Gray)+GradientMask)+And+Morph(Erode,16)+LargestConvexArea");
39 Globals->abbreviations.insert("DrawFaceDetection", "Open+Cascade(FrontalFace)+Expand+ASEFEyes+Draw(inPlace=true)"); 50 Globals->abbreviations.insert("DrawFaceDetection", "Open+Cascade(FrontalFace)+Expand+ASEFEyes+Draw(inPlace=true)");
40 Globals->abbreviations.insert("ShowFaceDetection", "DrawFaceDetection+Contract+First+Show+Discard"); 51 Globals->abbreviations.insert("ShowFaceDetection", "DrawFaceDetection+Contract+First+Show+Discard");
41 - Globals->abbreviations.insert("DownloadFaceRecognition", "Download+Open+ROI+Cvt(Gray)+Cascade(FrontalFace)+FaceRecognitionRegistration+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>+SetMetadata(AlgorithmID,-1):Unit(ByteL1)");  
42 Globals->abbreviations.insert("OpenBR", "FaceRecognition"); 52 Globals->abbreviations.insert("OpenBR", "FaceRecognition");
43 Globals->abbreviations.insert("GenderEstimation", "GenderClassification"); 53 Globals->abbreviations.insert("GenderEstimation", "GenderClassification");
44 Globals->abbreviations.insert("AgeEstimation", "AgeRegression"); 54 Globals->abbreviations.insert("AgeEstimation", "AgeRegression");
45 - Globals->abbreviations.insert("FaceRecognition2", "{PP5Register+Affine(128,128,0.25,0.35)+Cvt(Gray)}+(Gradient+HistBin(0,360,9,true))/(Blur(1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2,true)+HistBin(0,10,10,true))+Merge+Integral+RecursiveIntegralSampler(4,2,8,LDA(.98)+Normalize(L1))+Cat+PCA(768)+Normalize(L1)+Quantize:UCharL1");  
46 Globals->abbreviations.insert("CropFace", "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.25,0.35)"); 55 Globals->abbreviations.insert("CropFace", "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.25,0.35)");
47 - Globals->abbreviations.insert("4SF", "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.33,0.45)+(Grid(10,10)+SIFTDescriptor(12)+ByRow)/(Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59))+PCA(0.95)+Cat+Normalize(L2)+Dup(12)+RndSubspace(0.05,1)+LDA(0.98)+Cat+PCA(0.95)+Normalize(L1)+Quantize:NegativeLogPlusOne(ByteL1)"); 56 + Globals->abbreviations.insert("4SF", "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.33,0.45)+(Grid(10,10)+SIFTDescriptor(12)+ByRow)/(Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59))+PCA(0.95)+Cat+Normalize(L2)+Dup(12)+RndSubspace(0.05,1)+LDA(0.98)+Cat+PCA(0.95)+Normalize(L1):NegativeLogPlusOne(ByteL1)");
48 57
49 // Video 58 // Video
50 Globals->abbreviations.insert("DisplayVideo", "FPSLimit(30)+Show(false,[FrameNumber])+Discard"); 59 Globals->abbreviations.insert("DisplayVideo", "FPSLimit(30)+Show(false,[FrameNumber])+Discard");
@@ -92,9 +101,6 @@ class AlgorithmsInitializer : public Initializer @@ -92,9 +101,6 @@ class AlgorithmsInitializer : public Initializer
92 Globals->abbreviations.insert("DenseSIFT", "(Grid(10,10)+SIFTDescriptor(12)+ByRow)"); 101 Globals->abbreviations.insert("DenseSIFT", "(Grid(10,10)+SIFTDescriptor(12)+ByRow)");
93 Globals->abbreviations.insert("DenseSIFT2", "(Grid(5,5)+SIFTDescriptor(12)+ByRow)"); 102 Globals->abbreviations.insert("DenseSIFT2", "(Grid(5,5)+SIFTDescriptor(12)+ByRow)");
94 Globals->abbreviations.insert("FaceRecognitionRegistration", "ASEFEyes+Affine(88,88,0.25,0.35)"); 103 Globals->abbreviations.insert("FaceRecognitionRegistration", "ASEFEyes+Affine(88,88,0.25,0.35)");
95 - Globals->abbreviations.insert("FaceRecognitionExtraction", "(Mask+DenseSIFT/DenseLBP+DownsampleTraining(PCA(0.95),instances=1)+Normalize(L2)+Cat)");  
96 - Globals->abbreviations.insert("FaceRecognitionEmbedding", "(Dup(12)+RndSubspace(0.05,1)+DownsampleTraining(LDA(0.98),instances=-2)+Cat+DownsampleTraining(PCA(768),instances=1))");  
97 - Globals->abbreviations.insert("FaceRecognitionQuantization", "(Normalize(L1)+Quantize)");  
98 Globals->abbreviations.insert("FaceClassificationRegistration", "ASEFEyes+Affine(56,72,0.33,0.45)"); 104 Globals->abbreviations.insert("FaceClassificationRegistration", "ASEFEyes+Affine(56,72,0.33,0.45)");
99 Globals->abbreviations.insert("FaceClassificationExtraction", "((Grid(7,7)+SIFTDescriptor(8)+ByRow)/DenseLBP+DownsampleTraining(PCA(0.95),instances=-1, inputVariable=Gender)+Cat)"); 105 Globals->abbreviations.insert("FaceClassificationExtraction", "((Grid(7,7)+SIFTDescriptor(8)+ByRow)/DenseLBP+DownsampleTraining(PCA(0.95),instances=-1, inputVariable=Gender)+Cat)");
100 Globals->abbreviations.insert("AgeRegressor", "DownsampleTraining(Center(Range),instances=-1, inputVariable=Age)+DownsampleTraining(SVM(RBF,EPS_SVR,inputVariable=Age),instances=100, inputVariable=Age)"); 106 Globals->abbreviations.insert("AgeRegressor", "DownsampleTraining(Center(Range),instances=-1, inputVariable=Age)+DownsampleTraining(SVM(RBF,EPS_SVR,inputVariable=Age),instances=100, inputVariable=Age)");
openbr/plugins/imgproc/cropfromlandmarks.cpp
1 #include <openbr/plugins/openbr_internal.h> 1 #include <openbr/plugins/openbr_internal.h>
  2 +#include <openbr/core/opencvutils.h>
2 3
3 using namespace cv; 4 using namespace cv;
4 5
@@ -43,7 +44,13 @@ class CropFromLandmarksTransform : public UntrainableTransform @@ -43,7 +44,13 @@ class CropFromLandmarksTransform : public UntrainableTransform
43 int padW = qRound((maxX - minX) * (paddingHorizontal / 2)); 44 int padW = qRound((maxX - minX) * (paddingHorizontal / 2));
44 int padH = qRound((maxY - minY) * (paddingVertical / 2)); 45 int padH = qRound((maxY - minY) * (paddingVertical / 2));
45 46
46 - dst = Mat(src, Rect(minX - padW, minY - padH, (maxX - minX + 1) + padW * 2, (maxY - minY + 1) + padH * 2)); 47 + QRectF rect(minX - padW, minY - padH, (maxX - minX + 1) + padW * 2, (maxY - minY + 1) + padH * 2);
  48 + if (rect.x() < 0) rect.setX(0);
  49 + if (rect.y() < 0) rect.setY(0);
  50 + if (rect.x() + rect.width() > src.m().cols) rect.setWidth(src.m().cols - rect.x());
  51 + if (rect.y() + rect.width() > src.m().rows) rect.setHeight(src.m().rows - rect.y());
  52 +
  53 + dst = Mat(src, OpenCVUtils::toRect(rect));
47 } 54 }
48 }; 55 };
49 56
openbr/plugins/imgproc/scalemat.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2015 Rank One Computing
  3 + * *
  4 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  5 +
  6 +#include <opencv2/imgproc/imgproc.hpp>
  7 +
  8 +#include <openbr/plugins/openbr_internal.h>
  9 +
  10 +using namespace cv;
  11 +
  12 +namespace br
  13 +{
  14 +
  15 +/*!
  16 + * \ingroup transforms
  17 + * \brief Scales the mat values by provided factor
  18 + * \author Brendan Klare \cite bklare
  19 + */
  20 +class ScaleMatTransform : public UntrainableTransform
  21 +{
  22 + Q_OBJECT
  23 +
  24 + Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false)
  25 + BR_PROPERTY(float, scaleFactor, 1.)
  26 +
  27 + void project(const Template &src, Template &dst) const
  28 + {
  29 + dst = src * scaleFactor;
  30 + }
  31 +};
  32 +
  33 +BR_REGISTER(Transform, ScaleMatTransform)
  34 +
  35 +} // namespace br
  36 +
  37 +#include "imgproc/scalemat.moc"
scripts/BTASTutorial/representation.sh 0 → 100755
  1 +#!/bin/bash
  2 +
  3 +if [ ! -f meds.mask ]; then
  4 + br -makeMask ../../data/MEDS/sigset/MEDS_frontal_target.xml ../../data/MEDS/sigset/MEDS_frontal_query.xml meds.mask
  5 +fi
  6 +
  7 +PIXEL_ALG="Open+Cvt(Gray)+Cascade+ASEFEyes+Affine(88,88,0.25,0.35)+Blur(1)+Cat+Normalize(L2):Dist(L2)"
  8 +LBP_ALG="Open+Cvt(Gray)+Cascade+ASEFEyes+Affine(88,88,0.25,0.35)+Blur(1)+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59)+Normalize(L1)+Cat+Normalize(L2):Dist(L2)"
  9 +ALG="Open+Cvt(Gray)+Cascade+ASEFEyes+Affine(88,88,0.25,0.35)+Blur(1)+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59)+Normalize(L1)+Cat+LDA(0.95)+Normalize(L2):Dist(L2)"
  10 +
  11 +br -path $DATA/MEDS -algorithm "${PIXEL_ALG}" -compare ../../data/MEDS/sigset/MEDS_frontal_target.xml ../../data/MEDS/sigset/MEDS_frontal_query.xml meds.mtx -eval meds.mtx meds.mask Algorithm_Dataset/pixels_MEDS.csv
  12 +br -path $DATA/MEDS -algorithm "${ALG}" -compare ../../data/MEDS/sigset/MEDS_frontal_target.xml ../../data/MEDS/sigset/MEDS_frontal_query.xml meds.mtx -eval meds.mtx meds.mask Algorithm_Dataset/LBP_MEDS.csv
  13 +
  14 +br -path $DATA/LFW-original -algorithm "${ALG}" -train ../../data/LFW/sigset/LFW.xml representLDA.model
  15 +br -path $DATA/MEDS -algorithm representLDA.model -compare ../../data/MEDS/sigset/MEDS_frontal_target.xml ../../data/MEDS/sigset/MEDS_frontal_query.xml meds.mtx -eval meds.mtx meds.mask Algorithm_Dataset/LDA_MEDS.csv
  16 +
  17 +br -plot Algorithm_Dataset/* btasResults.pdf
scripts/evalFaceRecognition-BLUFR.sh 0 → 100644
  1 +#!/bin/bash
  2 +
  3 +#input algorithm string as argument
  4 +ALGORITHM=$1
  5 +
  6 +if [ ! -f evalFaceRecognition-BLUFR.sh ]; then
  7 + echo "Run this script from the scripts folder!"
  8 + exit
  9 +fi
  10 +
  11 +if ! hash br 2>/dev/null; then
  12 + echo "Can't find 'br'. Did you forget to build and install OpenBR? Here's some help: http://openbiometrics.org/docs/install/index.html"
  13 + exit
  14 +fi
  15 +
  16 +# Get the data
  17 +./downloadDatasets.sh
  18 +
  19 +if [ ! -e Algorithm_Split ]; then
  20 + mkdir Algorithm_Split
  21 +fi
  22 +
  23 +for i in `seq 1 10`; do
  24 + br -algorithm ${ALGORITHM} -path ../data/LFW/img -train ../data/LFW/sigset/BLUFR/split${i}/train${i}.xml -compare ../data/LFW/sigset/BLUFR/split${i}/gallery${i}.xml ../data/LFW/sigset/BLUFR/split${i}/probe${i}.xml Algorithm_Split/newAlgorithm_BLUFR${i}.eval
  25 +done
  26 +
  27 +br -plot Algorithm_Split/* BLUFR.pdf[smooth=Split]
0 \ No newline at end of file 28 \ No newline at end of file
1 -Subproject commit e0fa4314abdda0dea598f24609601e2323670969 1 +Subproject commit be38bd854f7a563818f153a15972f8495de7e80b
share/openbr/plotting/plot_utils.R
@@ -45,7 +45,7 @@ plotTable &lt;- function(tableData=NULL, name=NULL, labels=NULL) { @@ -45,7 +45,7 @@ plotTable &lt;- function(tableData=NULL, name=NULL, labels=NULL) {
45 input = tableData$Y 45 input = tableData$Y
46 } 46 }
47 mat <- matrix(input, nrow=length(labels), ncol=length(algs), byrow=FALSE) 47 mat <- matrix(input, nrow=length(labels), ncol=length(algs), byrow=FALSE)
48 - colnames(mat) <- algs 48 + colnames(mat) <- algs[order(tolower(algs))]
49 rownames(mat) <- labels 49 rownames(mat) <- labels
50 table <- as.table(mat) 50 table <- as.table(mat)
51 if (csv) { 51 if (csv) {