VisionUtils.cpp
Go to the documentation of this file.
00001 /****************************************************************
00002 *
00003 * Copyright (c) 2010
00004 *
00005 * Fraunhofer Institute for Manufacturing Engineering
00006 * and Automation (IPA)
00007 *
00008 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00009 *
00010 * Project name: care-o-bot
00011 * ROS stack name: cob_driver
00012 * ROS package name: cob_camera_sensors
00013 * Description:
00014 *
00015 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00016 *
00017 * Author: Jan Fischer, email:jan.fischer@ipa.fhg.de
00018 * Supervised by: Jan Fischer, email:jan.fischer@ipa.fhg.de
00019 *
00020 * Date of creation: Mai 2008
00021 * ToDo:
00022 *
00023 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00024 *
00025 * Redistribution and use in source and binary forms, with or without
00026 * modification, are permitted provided that the following conditions are met:
00027 *
00028 * * Redistributions of source code must retain the above copyright
00029 * notice, this list of conditions and the following disclaimer.
00030 * * Redistributions in binary form must reproduce the above copyright
00031 * notice, this list of conditions and the following disclaimer in the
00032 * documentation and/or other materials provided with the distribution.
00033 * * Neither the name of the Fraunhofer Institute for Manufacturing
00034 * Engineering and Automation (IPA) nor the names of its
00035 * contributors may be used to endorse or promote products derived from
00036 * this software without specific prior written permission.
00037 *
00038 * This program is free software: you can redistribute it and/or modify
00039 * it under the terms of the GNU Lesser General Public License LGPL as
00040 * published by the Free Software Foundation, either version 3 of the
00041 * License, or (at your option) any later version.
00042 *
00043 * This program is distributed in the hope that it will be useful,
00044 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00045 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00046 * GNU Lesser General Public License LGPL for more details.
00047 *
00048 * You should have received a copy of the GNU Lesser General Public
00049 * License LGPL along with this program.
00050 * If not, see <http://www.gnu.org/licenses/>.
00051 *
00052 ****************************************************************/
00053 
00054 #ifdef __LINUX__
00055 #include "cob_vision_utils/VisionUtils.h"
00056 #else
00057 #include "cob_perception_common/cob_vision_utils/common/include/cob_vision_utils/VisionUtils.h"
00058 #endif
00059 
00060 #include <fstream>
00061 
00062 using namespace ipa_Utils;
00063 
00064 cv::Mat ipa_Utils::vstack(const std::vector<cv::Mat> &mats)
00065 {
00066     if (mats.empty())
00067         return cv::Mat();
00068 
00069     // we need to know the total number of rows to create the stacked matrix
00070     int nRows = 0;
00071     int nCols = mats.front().cols;
00072     int datatype = mats.front().type();
00073     std::vector<cv::Mat>::const_iterator it;
00074     for (it = mats.begin(); it != mats.end(); ++it)
00075     {
00076         nRows += it->rows;
00077     }
00078 
00079     // copy data to stacked matrix
00080     int startRow = 0;
00081     int endRow = 0;
00082     cv::Mat stacked(nRows, nCols, datatype);
00083     for (it = mats.begin(); it != mats.end(); ++it)
00084     {
00085         if (it->rows == 0)
00086             continue;
00087 
00088         // make sure all mats have same num of cols and data type
00089         CV_Assert(it->cols == nCols);
00090         CV_Assert(it->type() == datatype);
00091 
00092         startRow = endRow;
00093         endRow = startRow + it->rows;
00094         cv::Mat mat = stacked.rowRange(startRow, endRow);
00095         it->copyTo(mat);
00096     }
00097 
00098     return stacked;
00099 }
00100 
00101 unsigned long ipa_Utils::EvaluatePolynomial(double x, int degree, double* coefficients, double* y)
00102 {
00103         (*y) = coefficients[degree];
00104         for (int i = degree-1; i >= 0; i--)
00105         {
00106                 (*y) *= x;
00107                 (*y) += coefficients[i];
00108         }
00109 
00110         return ipa_Utils::RET_OK;
00111 }
00112 
00113 void ipa_Utils::InitUndistortMap( const cv::Mat& _A, const cv::Mat& _dist_coeffs,
00114                     cv::Mat& _mapxarr, cv::Mat& _mapyarr )
00115 {
00116     uchar* buffer = 0;
00117 
00118         CvMat A = _A;
00119         CvMat dist_coeffs = _dist_coeffs;
00120         CvMat mapxarr = _mapxarr;
00121         CvMat mapyarr = _mapyarr;
00122 
00123     float a[9], k[4];
00124     int coi1 = 0, coi2 = 0;
00125     CvMat mapxstub, *_mapx = &mapxarr;
00126     CvMat mapystub, *_mapy = &mapyarr;
00127     float *mapx, *mapy;
00128     CvMat _a = cvMat( 3, 3, CV_32F, a ), _k;
00129     int mapxstep, mapystep;
00130     int u, v;
00131     float u0, v0, fx, fy, _fx, _fy, k1, k2, p1, p2;
00132     CvSize size;
00133 
00134     _mapx = cvGetMat( _mapx, &mapxstub, &coi1 );
00135     _mapy = cvGetMat( _mapy, &mapystub, &coi2 );
00136    
00137     cvConvert( &A, &_a );
00138     _k = cvMat( dist_coeffs.rows, dist_coeffs.cols,
00139                 CV_MAKETYPE(CV_32F, CV_MAT_CN(dist_coeffs.type)), k );
00140     cvConvert( &dist_coeffs, &_k );
00141 
00142     u0 = a[2]; v0 = a[5];
00143     fx = a[0]; fy = a[4];
00144     _fx = 1.f/fx; _fy = 1.f/fy;
00145     k1 = k[0]; k2 = k[1];
00146     p1 = k[2]; p2 = k[3];
00147 
00148     mapxstep = _mapx->step ? _mapx->step : (1<<30);
00149     mapystep = _mapy->step ? _mapy->step : (1<<30);
00150     mapx = _mapx->data.fl;
00151     mapy = _mapy->data.fl;
00152 
00153     size = cvGetSize(_mapx);
00154     
00155     mapxstep /= sizeof(mapx[0]);
00156     mapystep /= sizeof(mapy[0]);
00157 
00158     for( v = 0; v < size.height; v++, mapx += mapxstep, mapy += mapystep )
00159     {
00160         float y = (v - v0)*_fy;
00161         float y2 = y*y;
00162         float _2p1y = 2*p1*y;
00163         float _3p1y2 = 3*p1*y2;
00164         float p2y2 = p2*y2;
00165 
00166         for( u = 0; u < size.width; u++ )
00167         {
00168             float x = (u - u0)*_fx;
00169             float x2 = x*x;
00170             float r2 = x2 + y2;
00171             float d = 1 + (k1 + k2*r2)*r2;
00172             float _u = fx*(x*(d + _2p1y) + p2y2 + (3*p2)*x2) + u0;
00173             float _v = fy*(y*(d + (2*p2)*x) + _3p1y2 + p1*x2) + v0;
00174             mapx[u] = _u;
00175             mapy[u] = _v;
00176         }
00177     }
00178 
00179     cvFree( &buffer );
00180 }
00181 
00182 unsigned long ipa_Utils::MaskImage(const cv::Mat& source, cv::Mat& dest, const cv::Mat& mask, cv::Mat& destMask, float minMaskThresh, float maxMaskThresh,
00183                                                 int sourceChannel, double sourceMin, double sourceMax)
00184 {
00185         double globalMin = -1;
00186                 double globalMax = -1;
00187 
00188                 double maskMin = -1;
00189                 double maskMax = -1;
00190 
00191                 dest.create(source.rows, source.cols, CV_8UC3); 
00192 
00193                 CV_Assert(sourceChannel >= 1);
00194                 CV_Assert(sourceChannel <= source.channels());
00195 
00197                 CV_Assert(destMask.depth() == CV_8U);
00198                 CV_Assert(destMask.channels() == 3);
00199                 CV_Assert(destMask.cols == source.cols);
00200                 CV_Assert(destMask.rows == source.rows);
00201 
00203                 CV_Assert(mask.depth() == CV_32F);
00204                 CV_Assert(mask.channels() == 1);
00205                 CV_Assert(mask.cols == source.cols);
00206                 CV_Assert(mask.rows == source.rows);
00207 
00210                 if (sourceMin == -1 || sourceMax == -1)
00211                 {
00212                         cv::Mat mixImage(source.rows, source.cols, source.depth(), 1);
00213 
00214                         // Copy channel 2 of source to channel 0 of zSource
00215                         int from_to[] = {sourceChannel-1, 0};
00216 
00217                         cv::mixChannels(&source, 1, &mixImage, 1, from_to, 1);
00218                         cv::minMaxLoc(mixImage, &globalMin, &globalMax);
00219                 }
00220                 else
00221                 {
00222                         std::cerr << "ERROR - OpenCVUtils::MaskImage:" << std::endl;
00223                         std::cerr << "\t ... Parameter sourceChannel ('" << sourceChannel << "') out of range.\n";
00224                         return RET_FAILED;
00225                 }
00226                 
00227                 if (sourceMin == -1) sourceMin = globalMin;
00228                 if (sourceMax == -1) sourceMax = globalMax;
00229 
00230                 cv::minMaxLoc(mask, &maskMin, &maskMax);
00231                 double wMask = maskMax-maskMin;
00232 
00233                 double w = sourceMax-sourceMin;
00234                 int destIndex = 0;
00235                 int sourceIndex = 0;
00236                 int maskIndex = 0;
00237 
00238                 if (source.depth() == CV_32F)
00239                 {
00240                         for(int j=0; j<source.rows; j++)
00241                         {
00242                                 const float* f_source_ptr = source.ptr<float>(j);
00243                                 const float* f_mask_ptr = mask.ptr<float>(j);
00244                                 
00245                                 unsigned char* c_dest_ptr = dest.ptr<unsigned char>(j);
00246                                 unsigned char* c_destMask_ptr = destMask.ptr<unsigned char>(j);
00247                 
00248                                 for(int i=0; i<source.cols; i++)
00249                                 {
00250                                         unsigned char V = 0;
00251                                         unsigned char vMask = 0;
00252                                         destIndex = i*3;
00253                                         sourceIndex = i*source.channels();
00254                                         maskIndex = i*mask.channels();
00255 
00256                                         double z = (double)f_source_ptr[sourceIndex + sourceChannel - 1];
00257                                         float maskVal = f_mask_ptr[maskIndex];
00258                                         if (maskVal < maxMaskThresh &&
00259                                                 maskVal > minMaskThresh)
00260                                         {
00261                                                 if (z < sourceMin) 
00262                                                 {
00263                                                         z = sourceMin;
00264                                                         maskVal = (float)maskMin;
00265                                                 }
00266                                                 if (z > sourceMax)
00267                                                 {
00268                                                         z = sourceMax;
00269                                                         maskVal = (float)maskMax;
00270                                                 }
00271                                                 V= (unsigned char)(255.0 * ((z-sourceMin)/w));
00272 
00273                                                 vMask= (unsigned char)(255.0 * ((maskVal-globalMin)/wMask));
00274                                                 
00275                                         }
00276                                         else
00277                                         {
00278                                                 V = 0;
00279                                                 vMask = 0;
00280                                         }
00281 
00282                                         c_dest_ptr[destIndex] = V;
00283                                         c_dest_ptr[destIndex + 1] = V;
00284                                         c_dest_ptr[destIndex + 2] = V;
00285 
00286                                         c_destMask_ptr[destIndex] = vMask;
00287                                         c_destMask_ptr[destIndex + 1] = vMask;
00288                                         c_destMask_ptr[destIndex + 2] = vMask;
00289                                 }
00290                         }
00291                 }
00292                 else if (source.depth() == CV_32S)
00293                 {
00294                         for(int j=0; j<source.rows; j++)
00295                         {
00296                                 const float* f_mask_ptr = mask.ptr<float>(j);
00297                                 const int* i_source_ptr = source.ptr<int>(j);
00298                                 unsigned char* c_dest_ptr = dest.ptr<unsigned char>(j);
00299 
00300                                 for(int i=0; i<source.cols; i++)
00301                                 {
00302                                         int iTimes3 = i*3;
00303                                         unsigned char V = 0;
00304                 
00305                                         double z = (double)i_source_ptr[i*source.channels() + sourceChannel - 1];
00306                                 
00307                                         float maskVal = f_mask_ptr[maskIndex];
00308                                         if (maskVal < maxMaskThresh &&
00309                                                 maskVal > minMaskThresh)
00310                                         {
00311                                                 if (z < sourceMin) z = sourceMin;
00312                                                 if (z > sourceMax) z = sourceMax;
00313                                                 V = (unsigned char)(255.0 * ((z-sourceMin)/w));
00314                                         }
00315                                         else
00316                                         {
00317                                                 V = 0;
00318                                         }
00319 
00320                                         c_dest_ptr[iTimes3] = V;
00321                                         c_dest_ptr[iTimes3 + 1] = V;
00322                                         c_dest_ptr[iTimes3 + 2] = V;
00323                                 }
00324                         }
00325                 }
00326                 else if (source.depth() == CV_8U)
00327                 {
00328                         for(int j=0; j<source.rows; j++)
00329                         {
00330                                 const float* f_mask_ptr = mask.ptr<float>(j);
00331                                 const unsigned char* c_source_ptr = source.ptr<unsigned char>(j);
00332                                 unsigned char* c_dest_ptr = dest.ptr<unsigned char>(j);
00333 
00334                                 for(int i=0; i<source.cols; i++)
00335                                 {
00336                                         int iTimes3 = i*3;
00337                                         unsigned char V = 0;
00338                 
00339                                         double z = (double)c_source_ptr[i*source.channels() + sourceChannel - 1];
00340         
00341                                         float maskVal = f_mask_ptr[maskIndex];
00342                                         if (maskVal < maxMaskThresh &&
00343                                                 maskVal > minMaskThresh)
00344                                         {
00345                                                 if (z < sourceMin) z = sourceMin;
00346                                                 if (z > sourceMax) z = sourceMax;
00347                                                 V = (unsigned char)(255.0 * ((z-sourceMin)/w));
00348                                         }
00349                                         else
00350                                         {
00351                                                 V = 0;
00352                                         }
00353 
00354                                         c_dest_ptr[iTimes3] = V;
00355                                         c_dest_ptr[iTimes3 + 1] = V;
00356                                         c_dest_ptr[iTimes3 + 2] = V;
00357                                 }
00358                         }
00359                 }
00360                 else
00361                 {
00362                         std::cout << "ERROR - OpenCVUtils::MaskImage:" << std::endl;
00363                         std::cout << "\t ... Image depth of source not supported.\n";
00364                         return RET_FAILED;
00365                 }
00366                 
00367 
00368                 return RET_OK;
00369 }
00370 
00371 unsigned long ipa_Utils::ConvertToShowImage(const cv::Mat& source, cv::Mat& dest, int channel, double min, double max)
00372 {
00373         double globalMin = -1;
00374                 double globalMax = -1;
00375 
00376                 CV_Assert(channel >= 1);
00377                 CV_Assert(channel <= source.channels());
00378 
00379                 dest.create(source.rows, source.cols, CV_8UC3); 
00380 
00382                 cv::Mat mixImage(source.rows, source.cols, source.depth(), 1);
00383 
00384                 // Copy channel 2 of source to channel 0 of zSource
00385                 int from_to[] = {channel-1, 0};
00386 
00387                 cv::mixChannels(&source, 1, &mixImage, 1, from_to, 1);
00388                 cv::minMaxLoc(mixImage, &globalMin, &globalMax);
00389                                 
00390                 if (min == -1) min = globalMin;
00391                 if (max == -1) max = globalMax;
00392 
00393                 double w = max-min;
00394 
00395                 if (source.depth() == CV_32F)
00396                 {
00397                         for(int j=0; j<source.rows; j++)
00398                         {
00399                                 const float* f_source_ptr = source.ptr<float>(j);                               
00400                                 unsigned char* c_dest_ptr = dest.ptr<unsigned char>(j);
00401 
00402                                 for(int i=0; i<source.cols; i++)
00403                                 {
00404                                         int iTimes3 = i*3;
00405                 
00406                                         double z = (double)f_source_ptr[i*source.channels() + channel - 1];
00407                                         
00408                                         if (z < min) z = min;
00409                                         if (z > max) z = max;
00410 
00411                                         int V= (int)(255.0 * ((z-min)/w));
00412 
00413                                         c_dest_ptr[iTimes3] = V;
00414                                         c_dest_ptr[iTimes3 + 1] = V;
00415                                         c_dest_ptr[iTimes3 + 2] = V;
00416                                 }
00417                         }
00418                 }
00419                 else if (source.depth() == CV_32S)
00420                 {
00421                         for(int j=0; j<source.rows; j++)
00422                         {
00423                                 const int* i_source_ptr = source.ptr<int>(j);
00424                                 unsigned char* c_dest_ptr = dest.ptr<unsigned char>(j);
00425 
00426                                 for(int i=0; i<source.cols; i++)
00427                                 {
00428                                         int iTimes3 = i*3;
00429                 
00430                                         double z = (double)i_source_ptr[i*source.channels() + channel - 1];
00431                                 
00432                                         if (z < min) z = min;
00433                                         if (z > max) z = max;           
00434 
00435                                         int V= (int)(255.0 * ((z-min)/w));
00436 
00437                                         c_dest_ptr[iTimes3] = V;
00438                                         c_dest_ptr[iTimes3 + 1] = V;
00439                                         c_dest_ptr[iTimes3 + 2] = V;
00440                                 }
00441                         }
00442                 }
00443                 else if (source.depth() == CV_8U)
00444                 {
00445                         for(int j=0; j<source.rows; j++)
00446                         {
00447                                 const unsigned char* c_source_ptr = source.ptr<unsigned char>(j);
00448                                 unsigned char* c_dest_ptr = dest.ptr<unsigned char>(j);
00449 
00450                                 for(int i=0; i<source.cols; i++)
00451                                 {
00452                                         int iTimes3 = i*3;
00453                 
00454                                         double z = (double)c_source_ptr[i*source.channels() + channel - 1];
00455         
00456                                         if (z < min) z = min;
00457                                         if (z > max) z = max;
00458 
00459                                         int V= (int)(255.0 * ((z-min)/w));
00460 
00461                                         c_dest_ptr[iTimes3] = V;
00462                                         c_dest_ptr[iTimes3 + 1] = V;
00463                                         c_dest_ptr[iTimes3 + 2] = V;
00464                                 }
00465                         }
00466                 }
00467                 else
00468                 {
00469                         std::cout << "ERROR - OpenCVUtils::ConvertToShowImage:" << std::endl;
00470                         std::cout << "\t ... Image depth of source not supported.\n";
00471                         return RET_FAILED;
00472                 }
00473                 
00474 
00475                 return RET_OK;
00476 }
00477 
00478 unsigned long ipa_Utils::FilterByAmplitude(cv::Mat& xyzImage, const cv::Mat& greyImage, cv::Mat* mask, cv::Mat* maskColor, float minMaskThresh, float maxMaskThresh)
00479 {
00480         CV_Assert(xyzImage.type() == CV_32FC3);
00481         CV_Assert(greyImage.type() == CV_32FC1);
00482 
00483         if(mask) mask->create(greyImage.size(), CV_32FC1);
00484         if(maskColor) maskColor->create(greyImage.size(), CV_8UC3);
00485 
00486         int xyzIndex = 0;
00487         int maskColorIndex = 0;
00488         float V = 0;
00489         float vMask = 0;
00490 
00491         unsigned char* c_maskColor_ptr = 0;
00492         float* f_xyz_ptr = 0;
00493         const float* f_grey_ptr = 0;
00494         float* f_mask_ptr = 0;
00495 
00496         for(int j=0; j<xyzImage.rows; j++)
00497         {
00498                 f_xyz_ptr = xyzImage.ptr<float>(j);
00499                 f_grey_ptr = greyImage.ptr<float>(j);
00500                 if(mask) f_mask_ptr = mask->ptr<float>(j);
00501                 if(maskColor) c_maskColor_ptr = maskColor->ptr<unsigned char>(j);
00502 
00503                 for(int i=0; i<xyzImage.cols; i++)
00504                 {
00505                         
00506                         xyzIndex = i*3;
00507                         maskColorIndex = i*3;
00508 
00509                         double z = (double)f_xyz_ptr[xyzIndex + 2];
00510                         float maskVal = f_grey_ptr[i];
00511 
00512                         if(maskColor)
00513                         {
00515                                 if(maskVal>maxMaskThresh)
00516                                 {
00517                                         c_maskColor_ptr[maskColorIndex]= 0;
00518                                         c_maskColor_ptr[maskColorIndex+1]= 0;
00519                                         c_maskColor_ptr[maskColorIndex+2]= 255;
00520                                 }
00521                                 else if(maskVal<minMaskThresh)
00522                                 {
00523                                         c_maskColor_ptr[maskColorIndex]= 0;
00524                                         c_maskColor_ptr[maskColorIndex+1]= 255;
00525                                         c_maskColor_ptr[maskColorIndex+2]= 0;
00526                                 }
00527                                 else if(z<0.3)
00528                                 {
00529                                         c_maskColor_ptr[maskColorIndex]= 255;
00530                                         c_maskColor_ptr[maskColorIndex+1]= 0;
00531                                         c_maskColor_ptr[maskColorIndex+2]= 0;
00532                                 }
00533                                 else
00534                                 {
00535                                         c_maskColor_ptr[maskColorIndex]= 0;
00536                                         c_maskColor_ptr[maskColorIndex+1]= 0;
00537                                         c_maskColor_ptr[maskColorIndex+2]= 0;
00538                                 }
00539                         }
00540 
00541                         if (maskVal < maxMaskThresh &&
00542                                 maskVal > minMaskThresh)
00543                         {
00544                                 vMask = 0;
00545                         }
00546                         else
00547                         {
00548                                 vMask = 1;
00549                                 f_xyz_ptr[xyzIndex] = V;
00550                                 f_xyz_ptr[xyzIndex + 1] = V;
00551                                 f_xyz_ptr[xyzIndex + 2] = V;
00552                         }
00553 
00554                         if(mask)
00555                         {
00556                                 f_mask_ptr[i] = vMask;
00557                         }
00558 
00559                 }
00560         }
00561 
00562         return RET_OK;
00563 }
00564 
00565 unsigned long ipa_Utils::FilterTearOffEdges(cv::Mat& xyzImage, cv::Mat* mask, float piHalfFraction)
00566 {
00568         CV_Assert(xyzImage.type() == CV_32FC3);
00569 
00570         float pi = 3.14159f;
00571         float t_lower =pi/piHalfFraction;
00572         float t_upper = pi - t_lower;
00573 
00574         if(mask)
00575         {
00576                 mask->create(xyzImage.size() , CV_8UC3);
00577                 mask->setTo(0);
00578         }
00579 
00580         for(int row=0; row < xyzImage.rows; row++)
00581         {
00582                 int index_vLeft = -1;
00583                 int index_vMiddle = -1;
00584                 int index_vRight = -1;
00585                 int index_vUp = -1;
00586                 int index_vDown = -1;
00587 
00588                 cv::Vec3f vLeft = cv::Vec3f::all(0);
00589                 cv::Vec3f vMiddle = cv::Vec3f::all(0);
00590                 cv::Vec3f vRight = cv::Vec3f::all(0);
00591                 cv::Vec3f vUp = cv::Vec3f::all(0);
00592                 cv::Vec3f vDown = cv::Vec3f::all(0);
00593 
00594                 cv::Vec3f vDiff = cv::Vec3f::all(0);
00595 
00596                 float* f_image_ptr_RowUp = 0;
00597                 float* f_image_ptr_RowMiddle = 0;
00598                 float* f_image_ptr_RowDown = 0;
00599 
00600                 float dot = -1.f;
00601                 float angle = -1.f;
00602 
00603                 if (row-1 >= 0)
00604                 {
00605                         f_image_ptr_RowUp = xyzImage.ptr<float>(row-1);
00606                 }
00607 
00608                 f_image_ptr_RowMiddle = xyzImage.ptr<float>(row);
00609 
00610                 if (row+1 < xyzImage.rows)
00611                 {
00612                         f_image_ptr_RowDown = xyzImage.ptr<float>(row+1);
00613                 }
00614 
00621                 for(int col=0; col < xyzImage.cols; col++)
00622                 {
00624                         int score = 0;
00625 
00627                         index_vMiddle = col;
00628                         vMiddle[0] = f_image_ptr_RowMiddle[3*index_vMiddle];
00629                         vMiddle[1] = f_image_ptr_RowMiddle[3*index_vMiddle + 1];
00630                         vMiddle[2] = f_image_ptr_RowMiddle[3*index_vMiddle + 2];
00631 
00633                         if (col-1 >= 0)
00634                         {
00635                                 index_vLeft = col-1;
00636                                 vLeft[0] = f_image_ptr_RowMiddle[3*index_vLeft];
00637                                 vLeft[1] = f_image_ptr_RowMiddle[3*index_vLeft + 1];
00638                                 vLeft[2] = f_image_ptr_RowMiddle[3*index_vLeft + 2];
00639                                 vDiff = vLeft - vMiddle;
00640                                 float vLeftNorm = std::sqrt((vLeft[0] * vLeft[0]) + 
00641                                         (vLeft[1] * vLeft[1]) + (vLeft[2] * vLeft[2]));
00642                                 vLeft[0] = vLeft[0]/vLeftNorm;
00643                                 vLeft[1] = vLeft[1]/vLeftNorm;
00644                                 vLeft[2] = vLeft[2]/vLeftNorm;
00645                                 //vLeft.Normalize();
00646                                 float vDiffNorm = std::sqrt((vDiff[0] * vDiff[0]) +
00647                                         (vDiff[1] * vDiff[1]) + (vDiff[2] * vDiff[2]));
00648                                 vDiff[0] = vDiff[0]/vDiffNorm;
00649                                 vDiff[1] = vDiff[1]/vDiffNorm;
00650                                 vDiff[2] = vDiff[2]/vDiffNorm;
00651                                 //vDiff.Normalize();
00652                                 dot = (float)vDiff.ddot(vLeft);
00653                                 //dot = vDiff.Dot(vLeft);
00654                                 angle = (float)std::acos(dot);
00655                                 //angle = IPA_WM_VERSION::Math<float>::ACos( dot );
00656                                 if (angle > t_upper || angle < t_lower)
00657                                 {
00658                                         score++;
00659                                 }
00660                                 else
00661                                 {
00662                                         score--;
00663                                 }
00664                         }
00665 
00667                         if (col+1 < xyzImage.rows)
00668                         {
00669                                 index_vRight = col+1;
00670                                 vRight[0] = f_image_ptr_RowMiddle[3*index_vRight];
00671                                 vRight[1] = f_image_ptr_RowMiddle[3*index_vRight + 1];
00672                                 vRight[2] = f_image_ptr_RowMiddle[3*index_vRight + 2];
00673                                 vDiff = vRight - vMiddle;
00674                                 float vRightNorm = std::sqrt((vRight[0] * vRight[0]) + 
00675                                         (vRight[1] * vRight[1]) + (vRight[2] * vRight[2]));
00676                                 vRight[0] = vRight[0]/vRightNorm;
00677                                 vRight[1] = vRight[1]/vRightNorm;
00678                                 vRight[2] = vRight[2]/vRightNorm;
00679                                 //vRight.Normalize();
00680                                 float vDiffNorm = std::sqrt((vDiff[0] * vDiff[0]) +
00681                                         (vDiff[1] * vDiff[1]) + (vDiff[2] * vDiff[2]));
00682                                 vDiff[0] = vDiff[0]/vDiffNorm;
00683                                 vDiff[1] = vDiff[1]/vDiffNorm;
00684                                 vDiff[2] = vDiff[2]/vDiffNorm;
00685                                 //vDiff.Normalize();
00686                                 dot = (float)vDiff.ddot(vLeft);
00687                                 //dot = vDiff.Dot(vLeft);
00688                                 angle = (float)std::acos(dot);
00689                                 //angle = IPA_WM_VERSION::Math<float>::ACos( dot );
00690                                 if (angle > t_upper || angle < t_lower)
00691                                 {
00692                                         score++;
00693                                 }
00694                                 else
00695                                 {
00696                                         score--;
00697                                 }
00698                         }
00699 
00701                         if (f_image_ptr_RowUp)
00702                         {
00703                                 index_vUp = col;
00704                                 vUp[0] = f_image_ptr_RowUp[3*index_vUp];
00705                                 vUp[1] = f_image_ptr_RowUp[3*index_vUp + 1];
00706                                 vUp[2] = f_image_ptr_RowUp[3*index_vUp + 2];
00707                                 vDiff = vUp - vMiddle;
00708                                 float vUpNorm = std::sqrt((vUp[0] * vUp[0]) + 
00709                                         (vUp[1] * vUp[1]) + (vUp[2] * vUp[2]));
00710                                 vUp[0] = vUp[0]/vUpNorm;
00711                                 vUp[1] = vUp[1]/vUpNorm;
00712                                 vUp[2] = vUp[2]/vUpNorm;
00713                                 //vUp.Normalize();
00714                                 float vDiffNorm = std::sqrt((vDiff[0] * vDiff[0]) +
00715                                         (vDiff[1] * vDiff[1]) + (vDiff[2] * vDiff[2]));
00716                                 vDiff[0] = vDiff[0]/vDiffNorm;
00717                                 vDiff[1] = vDiff[1]/vDiffNorm;
00718                                 vDiff[2] = vDiff[2]/vDiffNorm;
00719                                 //vDiff.Normalize();
00720                                 dot = (float)vDiff.ddot(vLeft);
00721                                 //dot = vDiff.Dot(vLeft);
00722                                 angle = (float)std::acos(dot);
00723                                 //angle = IPA_WM_VERSION::Math<float>::ACos( dot );
00724                                 if (angle > t_upper || angle < t_lower)
00725                                 {
00726                                         score++;
00727                                 }
00728                                 else
00729                                 {
00730                                         score--;
00731                                 }
00732                         }
00733 
00735                         if (f_image_ptr_RowDown)
00736                         {
00737                                 index_vDown = col;
00738                                 vDown[0] = f_image_ptr_RowDown[3*index_vDown];
00739                                 vDown[1] = f_image_ptr_RowDown[3*index_vDown + 1];
00740                                 vDown[2] = f_image_ptr_RowDown[3*index_vDown + 2];
00741                                 float vDownNorm = std::sqrt((vDown[0] * vDown[0]) + 
00742                                         (vDown[1] * vDown[1]) + (vDown[2] * vDown[2]));
00743                                 vDown[0] = vDown[0]/vDownNorm;
00744                                 vDown[1] = vDown[1]/vDownNorm;
00745                                 vDown[2] = vDown[2]/vDownNorm;
00746                                 //vDown.Normalize();
00747                                 float vDiffNorm = std::sqrt((vDiff[0] * vDiff[0]) +
00748                                         (vDiff[1] * vDiff[1]) + (vDiff[2] * vDiff[2]));
00749                                 vDiff[0] = vDiff[0]/vDiffNorm;
00750                                 vDiff[1] = vDiff[1]/vDiffNorm;
00751                                 vDiff[2] = vDiff[2]/vDiffNorm;
00752                                 //vDiff.Normalize();
00753                                 dot = (float)vDiff.ddot(vLeft);
00754                                 //dot = vDiff.Dot(vLeft);
00755                                 angle = (float)std::acos(dot);
00756                                 //angle = IPA_WM_VERSION::Math<float>::ACos( dot );
00757                                 if (angle > t_upper || angle < t_lower)
00758                                 {
00759                                         score++;
00760                                 }
00761                                 else
00762                                 {
00763                                         score--;
00764                                 }
00765                         }
00766 
00767 
00769                         if (score > 0)
00770                         {
00771                                 cv::Vec3b pt(0, 0, 0);
00772                                 if(mask)
00773                                 {
00774                                         mask->at<cv::Vec3b>(row,col)=pt;
00775                                 }
00776 //                              xyzImage.at<cv::Vec3f>(row, col) = pt;
00777                                 for(int i = 0; i < 3; i++)
00778                                         ((float*)xyzImage.ptr(row))[3*col+i] = 0.f;
00779                         }
00780                 }
00781         }
00782 
00783         return ipa_Utils::RET_OK;
00784 }
00785 
00786 unsigned long ipa_Utils::FilterSpeckles(cv::Mat& img, int maxSpeckleSize, 
00787         double maxDiff, cv::Mat& _buf)
00788 {
00789     CV_Assert( img.type() == CV_32FC3 );
00790 
00791     float newVal = 0;
00792     int width = img.cols, height = img.rows, npixels = width*height;
00793     size_t bufSize = npixels*(int)(sizeof(cv::Point_<short>) + sizeof(int) + sizeof(uchar));
00794     if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize )
00795         _buf.create(1, bufSize, CV_8U);
00796     
00797     uchar* buf = _buf.data;
00798     int i, j, dstep = img.step/sizeof(cv::Vec3f);
00799     int* labels = (int*)buf;
00800     buf += npixels*sizeof(labels[0]);
00801     cv::Point_<short>* wbuf = (cv::Point_<short>*)buf;
00802     buf += npixels*sizeof(wbuf[0]);
00803     uchar* rtype = (uchar*)buf;
00804     int curlabel = 0;
00805     
00806     // clear out label assignments
00807     memset(labels, 0, npixels*sizeof(labels[0]));
00808     
00809     for( i = 0; i < height; i++ )
00810     {
00811                 cv::Vec3f* ds = img.ptr<cv::Vec3f>(i);
00812         int* ls = labels + width*i;
00813         
00814         for( j = 0; j < width; j++ )
00815         {
00816             if( ds[j][2] != newVal )    // not a bad disparity
00817             {
00818                 if( ls[j] )             // has a label, check for bad label
00819                 {  
00820                     if( rtype[ls[j]] ) // small region, zero out disparity
00821                                         {
00822                         ds[j][0] = (float)newVal;
00823                                                 ds[j][1] = (float)newVal;
00824                                                 ds[j][2] = (float)newVal;
00825                                         }
00826                 }
00827                 // no label, assign and propagate
00828                 else
00829                 {
00830                     cv::Point_<short>* ws = wbuf;       // initialize wavefront
00831                     cv::Point_<short> p((short)j, (short)i);    // current pixel
00832                     curlabel++; // next label
00833                     int count = 0;      // current region size
00834                     ls[j] = curlabel;
00835                     
00836                     // wavefront propagation
00837                     while( ws >= wbuf ) // wavefront not empty
00838                     {
00839                         count++;
00840                         // put neighbors onto wavefront
00841                                                 cv::Vec3f* dpp = &img.at<cv::Vec3f>(p.y, p.x);
00842                                                 cv::Vec3f dp = *dpp;
00843                         int* lpp = labels + width*p.y + p.x;
00844                         
00845                         if( p.x < width-1 && !lpp[+1] && dpp[+1][2] != newVal && std::abs(dp[2] - dpp[+1][2]) <= maxDiff )
00846                         {
00847                             lpp[+1] = curlabel;
00848                             *ws++ = cv::Point_<short>(p.x+1, p.y);
00849                         }
00850                         
00851                                                 if( p.x > 0 && !lpp[-1] && dpp[-1][2] != newVal && std::abs(dp[2] - dpp[-1][2]) <= maxDiff )
00852                         {
00853                             lpp[-1] = curlabel;
00854                             *ws++ = cv::Point_<short>(p.x-1, p.y);
00855                         }
00856                         
00857                         if( p.y < height-1 && !lpp[+width] && dpp[+dstep][2] != newVal && std::abs(dp[2] - dpp[+dstep][2]) <= maxDiff )
00858                         {
00859                             lpp[+width] = curlabel;
00860                             *ws++ = cv::Point_<short>(p.x, p.y+1);
00861                         }
00862                         
00863                         if( p.y > 0 && !lpp[-width] && dpp[-dstep][2] != newVal && std::abs(dp[2] - dpp[-dstep][2]) <= maxDiff )
00864                         {
00865                             lpp[-width] = curlabel;
00866                             *ws++ = cv::Point_<short>(p.x, p.y-1);
00867                         }
00868                         
00869                         // pop most recent and propagate
00870                         // NB: could try least recent, maybe better convergence
00871                         p = *--ws;
00872                     }
00873                     
00874                     // assign label type
00875                     if( count <= maxSpeckleSize )       // speckle region
00876                     {
00877                         rtype[ls[j]] = 1;       // small region label
00878                         ds[j][0] = (float)newVal;
00879                                                 ds[j][1] = (float)newVal;
00880                                                 ds[j][2] = (float)newVal;
00881                     }
00882                     else
00883                         rtype[ls[j]] = 0;       // large region label
00884                 }
00885             }
00886         }
00887     }
00888         return ipa_Utils::RET_OK;
00889 } 
00890    
00891 cv::Vec3b ipa_Utils::GrayColorMap(double value, double min,double max)
00892 {
00893     double rgb[3];
00894     max-=min;
00895     value-=min;
00896     rgb[0]=rgb[1]=rgb[2]=(unsigned char)(255*value/max);
00897     return cv::Vec3b(rgb[2], rgb[1], rgb[0]);
00898 }
00899 
00900 cv::Mat ipa_Utils::GetColorcoded(const cv::Mat& img_32F)
00901 {
00902     if (img_32F.empty())
00903         return img_32F;
00904 
00905     double minVal, maxVal;
00906     cv::minMaxLoc(img_32F, &minVal, &maxVal);
00907     return GetColorcoded(img_32F, minVal, maxVal);
00908 }
00909 
00910 cv::Mat ipa_Utils::GetColorcoded(const cv::Mat& img_32F, double min, double max)
00911 {
00912     double H,S,V;
00913     cv::Mat hsvImage(img_32F.size(), CV_8UC3);
00914     int hsvBlue = (int)(180*2/3);
00915     
00916     if (min > max)
00917     {
00918         std::swap(min, max);
00919     }
00920 
00921     double diff = max-min;
00922     if (diff == 0)
00923     {
00924         diff = 1;
00925     }
00926 
00927     bool hsv = false;
00928 
00929     for (int i = 0; i < img_32F.rows; i++)
00930     {
00931 
00932         for (int j = 0; j < img_32F.cols; j++)
00933         {
00934             double val = (double)img_32F.at<float>(i,j);
00935             val = std::max(std::min(max, val), min);
00936             val = ((val-min)/diff);
00937             if (hsv)
00938             {
00939                 if (val == 0)
00940                 {
00941                     H = 0;
00942                     S = 0;
00943                     V = 0;
00944                 }
00945                 else
00946                 {
00947                     H = val * hsvBlue;
00948                     S = 255;
00949                     V = 255;
00950                 }
00951 
00952                 hsvImage.at<cv::Vec3b>(i,j)[0] = (unsigned char) hsvBlue - H;
00953                 hsvImage.at<cv::Vec3b>(i,j)[1] = (unsigned char) S;
00954                 hsvImage.at<cv::Vec3b>(i,j)[2] = (unsigned char) V;
00955             }
00956             else
00957             {
00958                 hsvImage.at<cv::Vec3b>(i,j) = GrayColorMap(1-val, 0, 1);
00959             }
00960         }
00961     }
00962 
00963     if (hsv)
00964         cv::cvtColor(hsvImage, hsvImage, CV_HSV2BGR);
00965 
00966     return hsvImage;
00967 }
00968 
00969 unsigned long ipa_Utils::SaveMat(cv::Mat& mat, std::string filename, int type)
00970 {
00971         
00972 
00973         std::ofstream f(filename.c_str(), std::ios_base::binary);
00974         if(!f.is_open())
00975         {
00976                 std::cerr << "ERROR - ipa_Utils::SaveMat:" << std::endl;
00977                 std::cerr << "\t ... Could not open " << filename << " \n";
00978                 return ipa_Utils::RET_FAILED;
00979         }
00980 
00981         int channels = mat.channels();
00982         
00983         int header[3];
00984         header[0] = mat.rows;
00985         header[1] = mat.cols;
00986         header[2] = channels;
00987 
00988 #ifndef __LINUX__
00989         f.write((char*)header, 3 * sizeof(int));
00990 #else
00991         f.write((char const*)header, 3 * sizeof(int));
00992 #endif
00993 
00994         if (type == CV_32F)
00995         {
00996                 float* ptr = 0;
00997                 for(unsigned int row=0; row<(unsigned int)mat.rows; row++)
00998                 {
00999                         ptr = mat.ptr<float>(row);
01000                         f.write((char*)ptr, channels * mat.cols * sizeof(float));
01001                 }
01002         }
01003         if (type == CV_8U)
01004         {
01005                 unsigned char* ptr = 0;
01006                 for(unsigned int row=0; row<(unsigned int)mat.rows; row++)
01007                 {
01008                         ptr = mat.ptr<unsigned char>(row);
01009                         f.write((char*)ptr, channels * mat.cols * sizeof(unsigned char));
01010                 }
01011         }
01012 
01013         f.close();
01014         return ipa_Utils::RET_OK;
01015 }
01016 
01017 unsigned long ipa_Utils::LoadMat(cv::Mat& mat, std::string filename, int type)
01018 {
01019         size_t file_length = 0;
01020         char *c_string = 0;
01021 
01022         std::ifstream file(filename.c_str(), std::ios_base::binary|std::ios_base::in|std::ios_base::ate);
01023         if(!file.is_open())
01024         {
01025                 std::cerr << "ERROR - ipa_Utils::LoadMat:" << std::endl;
01026                 std::cerr << "\t ... Could not open " << filename << " \n";
01027                 return ipa_Utils::RET_FAILED;
01028         }
01029 
01030         file_length = file.tellg();
01031         file.seekg(0, std::ios_base::beg);
01032         file.clear();
01033 
01034         c_string = new char[file_length];
01035         file.read(c_string, file_length);
01036         
01037         unsigned int rows, cols;
01038         int channels;
01039         rows = ((int*)c_string)[0];
01040         cols = ((int*)c_string)[1];
01041         channels = ((int*)c_string)[2];
01042 
01043         char* c_ptr;
01044 
01045         if (type == CV_32F)
01046         {
01047                 float* f_ptr;
01048                 mat.create(rows, cols, CV_32FC(channels));
01049                 f_ptr = mat.ptr<float>(0);
01050                 c_ptr = &c_string[3 * sizeof(int)];
01051         
01052                 memcpy(f_ptr, c_ptr,  channels * mat.cols * mat.rows * sizeof(float));
01053         }
01054         if (type == CV_8U)
01055         {
01056                 unsigned char* f_ptr;
01057                 mat.create(rows, cols, CV_32FC(channels));
01058                 f_ptr = mat.ptr<unsigned char>(0);
01059                 c_ptr = &c_string[3 * sizeof(int)];
01060         
01061                 memcpy(f_ptr, c_ptr,  channels * mat.cols * mat.rows * sizeof(unsigned char));
01062         }
01063 
01064         file.close();
01065 
01066         delete[] c_string;
01067 
01068         return ipa_Utils::RET_OK;
01069 }
01070 
01071 ipa_Utils::UniqueNumber::UniqueNumber()
01072 {
01073     current=0;
01074 }
01075 
01076 int ipa_Utils::UniqueNumber::operator()() 
01077 {
01078     return current++;
01079 }


cob_vision_utils
Author(s): Jan Fischer
autogenerated on Thu Aug 27 2015 12:46:31