00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <opencv2/opencv.hpp>
00019 #include "helper.hpp"
00020
00021 using namespace cv;
00022
00023
00024
00025
00026 namespace cv
00027 {
00028
00029 template<typename _Tp> static bool isSymmetric_(InputArray src)
00030 {
00031 Mat _src = src.getMat();
00032 if (_src.cols != _src.rows)
00033 return false;
00034 for (int i = 0; i < _src.rows; i++)
00035 {
00036 for (int j = 0; j < _src.cols; j++)
00037 {
00038 _Tp a = _src.at<_Tp>(i, j);
00039 _Tp b = _src.at<_Tp>(j, i);
00040 if (a != b)
00041 {
00042 return false;
00043 }
00044 }
00045 }
00046 return true;
00047 }
00048
00049 template<typename _Tp> static bool isSymmetric_(InputArray src, double eps)
00050 {
00051 Mat _src = src.getMat();
00052 if (_src.cols != _src.rows)
00053 return false;
00054 for (int i = 0; i < _src.rows; i++)
00055 {
00056 for (int j = 0; j < _src.cols; j++)
00057 {
00058 _Tp a = _src.at<_Tp>(i, j);
00059 _Tp b = _src.at<_Tp>(j, i);
00060 if (std::abs(a - b) > eps)
00061 {
00062 return false;
00063 }
00064 }
00065 }
00066 return true;
00067 }
00068
00069 }
00070
00071 bool cv::isSymmetric(InputArray src, double eps)
00072 {
00073 Mat m = src.getMat();
00074 switch (m.type())
00075 {
00076 case CV_8SC1:
00077 return isSymmetric_<char>(m);
00078 break;
00079 case CV_8UC1:
00080 return isSymmetric_<unsigned char>(m);
00081 break;
00082 case CV_16SC1:
00083 return isSymmetric_<short>(m);
00084 break;
00085 case CV_16UC1:
00086 return isSymmetric_<unsigned short>(m);
00087 break;
00088 case CV_32SC1:
00089 return isSymmetric_<int>(m);
00090 break;
00091 case CV_32FC1:
00092 return isSymmetric_<float>(m, eps);
00093 break;
00094 case CV_64FC1:
00095 return isSymmetric_<double>(m, eps);
00096 break;
00097 default:
00098 break;
00099 }
00100 return false;
00101 }
00102
00103
00104
00105
00106 Mat cv::argsort(InputArray _src, bool ascending)
00107 {
00108 Mat src = _src.getMat();
00109 if (src.rows != 1 && src.cols != 1)
00110 {
00111 CV_Error(CV_StsBadArg, "cv::argsort only sorts 1D matrices.");
00112 }
00113 int flags = CV_SORT_EVERY_ROW + (ascending ? CV_SORT_ASCENDING : CV_SORT_DESCENDING);
00114 Mat sorted_indices;
00115 cv::sortIdx(src.reshape(1, 1), sorted_indices, flags);
00116 return sorted_indices;
00117 }
00118
00119
00120
00121 namespace cv
00122 {
00123
00124 static Mat histc_(const Mat& src, int minVal = 0, int maxVal = 255, bool normed = false)
00125 {
00126 Mat result;
00127
00128 int histSize = maxVal - minVal + 1;
00129
00130 float range[] =
00131 { minVal, maxVal + 1 };
00132 const float* histRange =
00133 { range };
00134
00135 calcHist(&src, 1, 0, Mat(), result, 1, &histSize, &histRange, true, false);
00136
00137 if (normed)
00138 {
00139 result /= src.total();
00140 }
00141 return result.reshape(1, 1);
00142 }
00143
00144 }
00145
00146 Mat cv::histc(InputArray _src, int minVal, int maxVal, bool normed)
00147 {
00148 Mat src = _src.getMat();
00149 switch (src.type())
00150 {
00151 case CV_8SC1:
00152 return histc_(Mat_<float>(src), minVal, maxVal, normed);
00153 break;
00154 case CV_8UC1:
00155 return histc_(src, minVal, maxVal, normed);
00156 break;
00157 case CV_16SC1:
00158 return histc_(Mat_<float>(src), minVal, maxVal, normed);
00159 break;
00160 case CV_16UC1:
00161 return histc_(src, minVal, maxVal, normed);
00162 break;
00163 case CV_32SC1:
00164 return histc_(Mat_<float>(src), minVal, maxVal, normed);
00165 break;
00166 case CV_32FC1:
00167 return histc_(src, minVal, maxVal, normed);
00168 break;
00169 default:
00170 CV_Error(CV_StsUnmatchedFormats, "This type is not implemented yet.");
00171 break;
00172 }
00173 return Mat();
00174 }
00175
00176
00177
00178
00179
00180 void cv::sortMatrixColumnsByIndices(InputArray _src, InputArray _indices, OutputArray _dst)
00181 {
00182 if (_indices.getMat().type() != CV_32SC1)
00183 {
00184 string error_message = format("cv::sortRowsByIndices only works on integer indices! Expected: %d. Given: %d.", CV_32SC1, _indices.getMat().type());
00185 CV_Error(CV_StsBadArg, error_message);
00186 }
00187 Mat src = _src.getMat();
00188 vector<int>indices = _indices.getMat();
00189 _dst.create(src.rows, src.cols, src.type());
00190 Mat dst = _dst.getMat();
00191 for (int idx = 0; idx < indices.size(); idx++)
00192 {
00193 Mat originalCol = src.col(indices[idx]);
00194 Mat sortedCol = dst.col(idx);
00195 originalCol.copyTo(sortedCol);
00196 }
00197 }
00198
00199 Mat cv::sortMatrixColumnsByIndices(InputArray src, InputArray indices)
00200 {
00201 Mat dst;
00202 sortMatrixColumnsByIndices(src, indices, dst);
00203 return dst;
00204 }
00205
00206
00207
00208
00209 void cv::sortMatrixRowsByIndices(InputArray _src, InputArray _indices, OutputArray _dst)
00210 {
00211 if (_indices.getMat().type() != CV_32SC1)
00212 {
00213 string error_message = format("cv::sortRowsByIndices only works on integer indices! Expected: %d. Given: %d.", CV_32SC1, _indices.getMat().type());
00214 CV_Error(CV_StsBadArg, error_message);
00215 }
00216 Mat src = _src.getMat();
00217 vector<int>indices = _indices.getMat();
00218 _dst.create(src.rows, src.cols, src.type());
00219 Mat dst = _dst.getMat();
00220 for (int idx = 0; idx < indices.size(); idx++)
00221 {
00222 Mat originalRow = src.row(indices[idx]);
00223 Mat sortedRow = dst.row(idx);
00224 originalRow.copyTo(sortedRow);
00225 }
00226 }
00227
00228 Mat cv::sortMatrixRowsByIndices(InputArray src, InputArray indices)
00229 {
00230 Mat dst;
00231 sortMatrixRowsByIndices(src, indices, dst);
00232 return dst;
00233 }
00234
00235
00236
00237
00238 Mat cv::asRowMatrix(InputArrayOfArrays src, int rtype, double alpha, double beta)
00239 {
00240
00241 if (src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR)
00242 {
00243 CV_Error(CV_StsBadArg, "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >).");
00244 }
00245
00246 size_t n = src.total();
00247
00248 if (n == 0)
00249 return Mat();
00250
00251 size_t d = src.getMat(0).total();
00252
00253 Mat data(n, d, rtype);
00254
00255 for (int i = 0; i < n; i++)
00256 {
00257
00258 if (src.getMat(i).total() != d)
00259 {
00260 string error_message = format("Wrong number of elements in matrix #%d! Expected %d was %d.", i, d, src.getMat(i).total());
00261 CV_Error(CV_StsBadArg, error_message);
00262 }
00263
00264 Mat xi = data.row(i);
00265
00266 if (src.getMat(i).isContinuous())
00267 {
00268 src.getMat(i).reshape(1, 1).convertTo(xi, rtype, alpha, beta);
00269 }
00270 else
00271 {
00272 src.getMat(i).clone().reshape(1, 1).convertTo(xi, rtype, alpha, beta);
00273 }
00274 }
00275 return data;
00276 }
00277
00278
00279
00280
00281 Mat cv::asColumnMatrix(InputArrayOfArrays src, int rtype, double alpha, double beta)
00282 {
00283
00284 if (src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR)
00285 {
00286 CV_Error(CV_StsBadArg, "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >).");
00287 }
00288 int n = (int)src.total();
00289
00290 if (n == 0)
00291 return Mat();
00292
00293 int d = src.getMat(0).total();
00294
00295 Mat data(d, n, rtype);
00296
00297 for (int i = 0; i < n; i++)
00298 {
00299
00300 if (src.getMat(i).total() != d)
00301 {
00302 string error_message = format("Wrong number of elements in matrix #%d! Expected %d was %d.", i, d, src.getMat(i).total());
00303 CV_Error(CV_StsBadArg, error_message);
00304 }
00305
00306 Mat yi = data.col(i);
00307
00308 if (src.getMat(i).isContinuous())
00309 {
00310 src.getMat(i).reshape(1, d).convertTo(yi, rtype, alpha, beta);
00311 }
00312 else
00313 {
00314 src.getMat(i).clone().reshape(1, d).convertTo(yi, rtype, alpha, beta);
00315 }
00316 }
00317 return data;
00318 }
00319