00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <new>
00042
00043 #include "ImageProcessorCV.h"
00044
00045 #include "IplImageAdaptor.h"
00046 #include "ByteImage.h"
00047 #include "Math/Math2d.h"
00048
00049 #include <stdio.h>
00050
00051
00052
00053
00054
00055
00056
00057 void ImageProcessorCV::FlipY(CByteImage *pInputImage, CByteImage *pOutputImage)
00058 {
00059 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00060 pInputImage->type != pOutputImage->type)
00061 return;
00062
00063 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00064 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00065
00066 cvFlip(pIplInputImage, pIplOutputImage);
00067
00068 cvReleaseImageHeader(&pIplInputImage);
00069 cvReleaseImageHeader(&pIplOutputImage);
00070 }
00071
00072 void ImageProcessorCV::GaussianSmooth3x3(CByteImage *pInputImage, CByteImage *pOutputImage)
00073 {
00074 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00075 pInputImage->type != pOutputImage->type)
00076 return;
00077
00078 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00079 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00080
00081 cvSmooth(pIplInputImage, pIplOutputImage, CV_GAUSSIAN, 3, 3);
00082
00083 cvReleaseImageHeader(&pIplInputImage);
00084 cvReleaseImageHeader(&pIplOutputImage);
00085 }
00086
00087 void ImageProcessorCV::GaussianSmooth5x5(CByteImage *pInputImage, CByteImage *pOutputImage)
00088 {
00089 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00090 pInputImage->type != pOutputImage->type)
00091 return;
00092
00093 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00094 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00095
00096 cvSmooth(pIplInputImage, pIplOutputImage, CV_GAUSSIAN, 5, 5);
00097
00098 cvReleaseImageHeader(&pIplInputImage);
00099 cvReleaseImageHeader(&pIplOutputImage);
00100 }
00101
00102 void ImageProcessorCV::BilateralSmooth(CByteImage *pInputImage, CByteImage *pOutputImage, int param1, int param2)
00103 {
00104 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00105 pInputImage->type != pOutputImage->type)
00106 return;
00107
00108 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00109 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00110
00111 cvSmooth(pIplInputImage, pIplOutputImage, CV_BILATERAL, param1, param2);
00112
00113 cvReleaseImageHeader(&pIplInputImage);
00114 cvReleaseImageHeader(&pIplOutputImage);
00115
00116 }
00117
00118 void ImageProcessorCV::Laplacian3x3(CByteImage *pInputImage, CByteImage *pOutputImage)
00119 {
00120 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00121 pInputImage->type != pOutputImage->type)
00122 return;
00123
00124 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00125 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00126 IplImage *pIplTempImage = cvCreateImage(cvSize(pInputImage->width, pInputImage->height), IPL_DEPTH_16S, 1);
00127
00128 cvLaplace(pIplInputImage, pIplTempImage, 1);
00129 cvConvertScaleAbs(pIplTempImage, pIplOutputImage);
00130
00131 cvReleaseImage(&pIplTempImage);
00132 cvReleaseImageHeader(&pIplInputImage);
00133 cvReleaseImageHeader(&pIplOutputImage);
00134 }
00135
00136 void ImageProcessorCV::Laplacian5x5(CByteImage *pInputImage, CByteImage *pOutputImage)
00137 {
00138 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00139 pInputImage->type != pOutputImage->type || pInputImage->type != CByteImage::eGrayScale)
00140 return;
00141
00142 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00143 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00144 IplImage *pIplTempImage = cvCreateImage(cvSize(pInputImage->width, pInputImage->height), IPL_DEPTH_16S, 1);
00145
00146 cvLaplace(pIplInputImage, pIplTempImage, 5);
00147 cvConvertScaleAbs(pIplTempImage, pIplOutputImage);
00148
00149 cvReleaseImage(&pIplTempImage);
00150 cvReleaseImageHeader(&pIplInputImage);
00151 cvReleaseImageHeader(&pIplOutputImage);
00152 }
00153
00154 void ImageProcessorCV::Resize(const CByteImage *pInputImage, CByteImage *pOutputImage, int x, int y, int width, int height)
00155 {
00156 if (pInputImage->type != pOutputImage->type)
00157 return;
00158
00159 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00160 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00161
00162 if (x != -1)
00163 cvSetImageROI(pIplInputImage, cvRect(x, y, width, height));
00164
00165 cvResize(pIplInputImage, pIplOutputImage);
00166
00167 cvReleaseImageHeader(&pIplInputImage);
00168 cvReleaseImageHeader(&pIplOutputImage);
00169 }
00170
00171 void ImageProcessorCV::CalculateGradientImage(CByteImage *pInputImage, CByteImage *pOutputImage)
00172 {
00173 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00174 pOutputImage->type != CByteImage::eGrayScale)
00175 return;
00176
00177 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00178 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00179
00180 if (pInputImage->type == CByteImage::eGrayScale)
00181 {
00182 IplImage *diff = cvCreateImage(cvSize(pInputImage->width, pInputImage->height), IPL_DEPTH_16S, 1);
00183 IplImage *abs = cvCreateImage(cvSize(pInputImage->width, pInputImage->height), IPL_DEPTH_8U, 1);
00184
00185 cvSmooth(pIplInputImage, abs, CV_GAUSSIAN, 3, 3);
00186 cvSobel(abs, diff, 1, 0, 3);
00187 cvConvertScaleAbs(diff, pIplOutputImage);
00188 cvSobel(abs, diff, 0, 1, 3);
00189 cvConvertScaleAbs(diff, abs);
00190 cvAdd(abs, pIplOutputImage, pIplOutputImage, 0);
00191
00192 cvReleaseImage(&diff);
00193 cvReleaseImage(&abs);
00194 }
00195 else if (pInputImage->type == CByteImage::eRGB24)
00196 {
00197
00198
00199 IplImage *singleChannel0 = cvCreateImage(cvSize(pInputImage->width,pInputImage->height), IPL_DEPTH_8U, 1);
00200 IplImage *singleChannel1 = cvCreateImage(cvSize(pInputImage->width,pInputImage->height), IPL_DEPTH_8U, 1);
00201 IplImage *singleChannel2 = cvCreateImage(cvSize(pInputImage->width,pInputImage->height), IPL_DEPTH_8U, 1);
00202 IplImage *diff = cvCreateImage(cvSize(pInputImage->width, pInputImage->height), IPL_DEPTH_16S, 1);
00203 IplImage *abs = cvCreateImage(cvSize(pInputImage->width, pInputImage->height), IPL_DEPTH_8U, 1);
00204
00205 cvCvtPixToPlane(pIplInputImage, singleChannel0, singleChannel1, singleChannel2, NULL);
00206
00207 cvSmooth(singleChannel0, singleChannel0, CV_GAUSSIAN, 3, 3);
00208 cvSobel(singleChannel0, diff, 1, 0, 3);
00209 cvConvertScaleAbs(diff, abs);
00210 cvSobel(singleChannel0, diff, 0, 1, 3);
00211 cvConvertScaleAbs(diff, singleChannel0);
00212 cvAdd(abs, singleChannel0, pIplOutputImage, 0);
00213
00214 cvSmooth(singleChannel1, singleChannel1, CV_GAUSSIAN, 3, 3);
00215 cvSobel(singleChannel1, diff, 1, 0, 3);
00216 cvConvertScaleAbs(diff, abs);
00217 cvSobel(singleChannel1, diff, 0, 1, 3);
00218 cvConvertScaleAbs(diff, singleChannel1);
00219 cvAdd(abs, singleChannel1, singleChannel1, 0);
00220 cvMax(pIplOutputImage, singleChannel1, pIplOutputImage);
00221
00222 cvSmooth(singleChannel2, singleChannel2, CV_GAUSSIAN, 3, 3);
00223 cvSobel(singleChannel2, diff, 1, 0, 3);
00224 cvConvertScaleAbs(diff, abs);
00225 cvSobel(singleChannel2, diff, 0, 1, 3);
00226 cvConvertScaleAbs(diff, singleChannel2);
00227 cvAdd(abs, singleChannel2, singleChannel2, 0);
00228 cvMax(pIplOutputImage, singleChannel2, pIplOutputImage);
00229
00230 cvReleaseImage(&singleChannel0);
00231 cvReleaseImage(&singleChannel1);
00232 cvReleaseImage(&singleChannel2);
00233 cvReleaseImage(&diff);
00234 cvReleaseImage(&abs);
00235 }
00236
00237 cvReleaseImageHeader(&pIplInputImage);
00238 cvReleaseImageHeader(&pIplOutputImage);
00239 }
00240
00241 void ImageProcessorCV::CalculateGradientImageHSV(CByteImage *pInputImage, CByteImage *pOutputImage)
00242 {
00243 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00244 pInputImage->type != CByteImage::eRGB24 || pOutputImage->type != CByteImage::eGrayScale)
00245 return;
00246
00247 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00248 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00249
00250
00251
00252 IplImage *singleChannel0 = cvCreateImage(cvSize(pInputImage->width,pInputImage->height), IPL_DEPTH_8U, 1);
00253 IplImage *singleChannel1 = cvCreateImage(cvSize(pInputImage->width,pInputImage->height), IPL_DEPTH_8U, 1);
00254 IplImage *singleChannel2 = cvCreateImage(cvSize(pInputImage->width,pInputImage->height), IPL_DEPTH_8U, 1);
00255 IplImage *diff = cvCreateImage(cvSize(pInputImage->width, pInputImage->height), IPL_DEPTH_16S, 1);
00256 IplImage *abs = cvCreateImage(cvSize(pInputImage->width, pInputImage->height), IPL_DEPTH_8U, 1);
00257
00258 cvCvtPixToPlane(pIplInputImage, singleChannel0, singleChannel1, singleChannel2, NULL);
00259
00260
00261
00262 cvSobel(singleChannel1, diff, 1, 0, 3);
00263 cvConvertScaleAbs(diff, abs);
00264 cvSobel(singleChannel1, diff, 0, 1, 3);
00265 cvConvertScaleAbs(diff, pIplOutputImage);
00266 cvAdd(abs, pIplOutputImage, pIplOutputImage, 0);
00267
00268
00269 cvThreshold(singleChannel1, singleChannel1, 60, 255, CV_THRESH_BINARY);
00270 cvDilate(singleChannel1, singleChannel1);
00271
00272
00273
00274 cvSobel(singleChannel0, diff, 1, 0, 3);
00275 cvConvertScaleAbs(diff, abs);
00276 cvSobel(singleChannel0, diff, 0, 1, 3);
00277 cvConvertScaleAbs(diff, singleChannel0);
00278 cvAdd(abs, singleChannel0, singleChannel0, 0);
00279
00280
00281 cvAnd(singleChannel0, singleChannel1, singleChannel0);
00282
00283
00284 cvMax(pIplOutputImage, singleChannel0, pIplOutputImage);
00285
00286
00287 cvReleaseImage(&singleChannel0);
00288 cvReleaseImage(&singleChannel1);
00289 cvReleaseImage(&singleChannel2);
00290 cvReleaseImage(&diff);
00291 cvReleaseImage(&abs);
00292
00293 cvReleaseImageHeader(&pIplInputImage);
00294 cvReleaseImageHeader(&pIplOutputImage);
00295 }
00296
00297 void ImageProcessorCV::Canny(CByteImage *pInputImage, CByteImage *pOutputImage, int nLowThreshold, int nHighThreshold)
00298 {
00299 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00300 pInputImage->type != pOutputImage->type || pInputImage->type != CByteImage::eGrayScale)
00301 return;
00302
00303 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00304 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00305
00306 cvCanny(pIplInputImage, pIplOutputImage, nLowThreshold, nHighThreshold);
00307
00308 cvReleaseImageHeader(&pIplInputImage);
00309 cvReleaseImageHeader(&pIplOutputImage);
00310 }
00311
00312 void ImageProcessorCV::Dilate(CByteImage *pInputImage, CByteImage *pOutputImage)
00313 {
00314 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00315 pInputImage->type != pOutputImage->type || pInputImage->type != CByteImage::eGrayScale)
00316 return;
00317
00318 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00319 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00320
00321 cvDilate(pIplInputImage, pIplOutputImage);
00322
00323 cvReleaseImageHeader(&pIplInputImage);
00324 cvReleaseImageHeader(&pIplOutputImage);
00325 }
00326
00327 void ImageProcessorCV::Erode(CByteImage *pInputImage, CByteImage *pOutputImage)
00328 {
00329 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00330 pInputImage->type != pOutputImage->type || pInputImage->type != CByteImage::eGrayScale)
00331 return;
00332
00333 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00334 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00335
00336 cvErode(pIplInputImage, pIplOutputImage);
00337
00338 cvReleaseImageHeader(&pIplInputImage);
00339 cvReleaseImageHeader(&pIplOutputImage);
00340 }
00341
00342 double ImageProcessorCV::Mean(CByteImage *pImage1, CByteImage *pImage2)
00343 {
00344 if (pImage1->width != pImage2->width || pImage1->height != pImage2->height ||
00345 pImage1->type != pImage2->type || pImage1->type != CByteImage::eGrayScale)
00346 return -1;
00347
00348 IplImage *pIplImage1 = IplImageAdaptor::Adapt(pImage1);
00349 IplImage *pIplImage2 = IplImageAdaptor::Adapt(pImage2);
00350
00351 double dRet = cvMean(pIplImage1, pIplImage2);
00352
00353 cvReleaseImageHeader(&pIplImage1);
00354 cvReleaseImageHeader(&pIplImage2);
00355
00356 return dRet;
00357 }
00358
00359 void ImageProcessorCV::CalculateHSVImage(CByteImage *pInputImage, CByteImage *pOutputImage)
00360 {
00361 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00362 pInputImage->type != pOutputImage->type || pInputImage->type != CByteImage::eRGB24)
00363 {
00364 printf("error: input and output image do not match for ImageProcessorCV::CalculateHSVImage\n");
00365 return;
00366 }
00367
00368 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00369 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00370
00371 cvCvtColor(pIplInputImage, pIplOutputImage, CV_RGB2HSV);
00372
00373 cvReleaseImageHeader(&pIplInputImage);
00374 cvReleaseImageHeader(&pIplOutputImage);
00375 }
00376
00377 void ImageProcessorCV::ConvertBayerPattern(CByteImage *pInputImage, CByteImage *pOutputImage, BayerPatternType type)
00378 {
00379 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00380 pInputImage->type != CByteImage::eGrayScale || pOutputImage->type != CByteImage::eRGB24)
00381 {
00382 printf("error: input and output image do not match for ImageProcessorCV::ConvertBayerPattern\n");
00383 return;
00384 }
00385
00386 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00387 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00388
00389 switch (type)
00390 {
00391 case eBG2BGR: cvCvtColor(pIplInputImage, pIplOutputImage, CV_BayerBG2BGR); break;
00392 case eGB2BGR: cvCvtColor(pIplInputImage, pIplOutputImage, CV_BayerGB2BGR); break;
00393 case eRG2BGR: cvCvtColor(pIplInputImage, pIplOutputImage, CV_BayerRG2BGR); break;
00394 case eGR2BGR: cvCvtColor(pIplInputImage, pIplOutputImage, CV_BayerGR2BGR); break;
00395 case eBG2RGB: cvCvtColor(pIplInputImage, pIplOutputImage, CV_BayerBG2RGB); break;
00396 case eGB2RGB: cvCvtColor(pIplInputImage, pIplOutputImage, CV_BayerGB2RGB); break;
00397 case eRG2RGB: cvCvtColor(pIplInputImage, pIplOutputImage, CV_BayerRG2RGB); break;
00398 case eGR2RGB: cvCvtColor(pIplInputImage, pIplOutputImage, CV_BayerGR2RGB); break;
00399 }
00400
00401 cvReleaseImageHeader(&pIplInputImage);
00402 cvReleaseImageHeader(&pIplOutputImage);
00403 }
00404
00405 int ImageProcessorCV::CalculateFeaturePoints(const CByteImage *pImage, Vec2d *pFeaturePoints, int nMaxPoints, float fQualityLevel, float fMinDistance, bool bUseHarris)
00406 {
00407 if (pImage->type != CByteImage::eGrayScale)
00408 {
00409 printf("error: input image is not grayscale in ImageProcessorCV::CalculateFeaturePoints\n");
00410 return -1;
00411 }
00412
00413 IplImage *pIplImage = IplImageAdaptor::Adapt(pImage);
00414 IplImage *pEigenvalueImage = cvCreateImage(cvSize(pImage->width, pImage->height), IPL_DEPTH_32F, 1);
00415 IplImage *pTempImage = cvCreateImage(cvSize(pImage->width, pImage->height), IPL_DEPTH_32F, 1);
00416
00417 CvPoint2D32f *pCorners = new CvPoint2D32f[nMaxPoints];
00418 int nCorners = nMaxPoints;
00419
00420 if (bUseHarris)
00421 cvGoodFeaturesToTrack(pIplImage, pEigenvalueImage, pTempImage, pCorners, &nCorners, fQualityLevel, fMinDistance, 0, 3, 1, 0.04);
00422 else
00423 cvGoodFeaturesToTrack(pIplImage, pEigenvalueImage, pTempImage, pCorners, &nCorners, fQualityLevel, fMinDistance, 0, 3);
00424
00425 for (int i = 0; i < nCorners; i++)
00426 {
00427 pFeaturePoints[i].x = pCorners[i].x;
00428 pFeaturePoints[i].y = pCorners[i].y;
00429 }
00430
00431 delete [] pCorners;
00432
00433 cvReleaseImageHeader(&pIplImage);
00434 cvReleaseImage(&pTempImage);
00435 cvReleaseImage(&pEigenvalueImage);
00436
00437 return nCorners;
00438 }
00439
00440 void ImageProcessorCV::ConvertImage(CByteImage *pInputImage, CByteImage *pOutputImage)
00441 {
00442 if (pInputImage->width != pOutputImage->width || pInputImage->height != pOutputImage->height ||
00443 pInputImage->type == pOutputImage->type)
00444 {
00445 printf("error: input and output image do not match for ImageProcessorCV::ConvertImage\n");
00446 return;
00447 }
00448
00449 IplImage *pIplInputImage = IplImageAdaptor::Adapt(pInputImage);
00450 IplImage *pIplOutputImage = IplImageAdaptor::Adapt(pOutputImage);
00451
00452 if (pInputImage->type == CByteImage::eRGB24)
00453 cvCvtColor(pIplInputImage, pIplOutputImage, CV_RGB2GRAY);
00454 else
00455 cvCvtColor(pIplInputImage, pIplOutputImage, CV_GRAY2RGB);
00456
00457 cvReleaseImageHeader(&pIplInputImage);
00458 cvReleaseImageHeader(&pIplOutputImage);
00459 }