22 #include "MEImage.hpp" 24 #include <MCBinaryData.hpp> 27 #include <MCSampleStatistics.hpp> 29 #include <opencv/cv.h> 30 #ifndef __AIBO_BUILD__ 31 #include <opencv/highgui.h> 34 #include <jpeglib_aiboplus.h> 35 #include <jerror_aiboplus.h> 37 #include <boost/foreach.hpp> 38 #include <boost/scoped_ptr.hpp> 40 #define RELEASE_IPLIMAGE(image_ptr) \ 42 cvReleaseImage(&image_ptr); \ 43 image_ptr = nullptr; \ 49 const float RGBtoYUVMatrix[3][3] =
50 {{ 0.299, 0.587, 0.114 },
51 { -0.147, -0.289, 0.436 },
52 { 0.615, -0.515, -0.100 }};
55 const float RGBtoYIQMatrix[3][3] =
56 {{ 0.299, 0.587, 0.114 },
57 { 0.596, -0.274, -0.322 },
58 { 0.212, -0.523, 0.311 }};
60 void AlternateExit(j_common_ptr cinfo)
63 (*cinfo->err->output_message)(cinfo);
70 void AlternatePrint(j_common_ptr cinfo)
72 char buffer[JMSG_LENGTH_MAX];
75 (*cinfo->err->format_message) (cinfo, buffer);
80 void AlternatePrintNoEcho(j_common_ptr)
86 void InitJpegBuffer(jpeg_compress_struct*)
92 boolean EmptyJpegBuffer(jpeg_compress_struct*)
99 void FinalizeJpegBuffer(jpeg_compress_struct*)
104 int EncodeJpeg(
unsigned char* input_buffer,
int row_width,
int width,
int height,
105 unsigned char* output_buffer,
int output_buffer_size,
106 int jpeg_quality,
bool grayscale)
111 struct jpeg_compress_struct CompressInfo;
112 struct jpeg_error_mgr JErr;
113 struct jpeg_destination_mgr DestManager;
115 DestManager.init_destination = InitJpegBuffer;
116 DestManager.empty_output_buffer = EmptyJpegBuffer;
117 DestManager.term_destination = FinalizeJpegBuffer;
118 DestManager.next_output_byte = (JOCTET*)output_buffer;
119 DestManager.free_in_buffer = output_buffer_size;
121 CompressInfo.err = jpeg_std_error(&JErr);
122 CompressInfo.err->error_exit = AlternateExit;
123 CompressInfo.err->output_message = AlternatePrint;
124 jpeg_create_compress(&CompressInfo);
125 CompressInfo.dest = &DestManager;
126 CompressInfo.image_width = width;
127 CompressInfo.image_height = height;
130 CompressInfo.input_components = 1;
131 CompressInfo.in_color_space = JCS_GRAYSCALE;
133 CompressInfo.input_components = 3;
134 CompressInfo.in_color_space = JCS_RGB;
137 jpeg_set_defaults(&CompressInfo);
138 jpeg_set_quality(&CompressInfo, jpeg_quality,
true);
139 jpeg_start_compress(&CompressInfo,
true);
143 while (CompressInfo.next_scanline < CompressInfo.image_height)
145 RowPointer = (JSAMPROW)&input_buffer[CompressInfo.next_scanline*row_width];
146 jpeg_write_scanlines(&CompressInfo, &RowPointer, 1);
148 jpeg_finish_compress(&CompressInfo);
150 JpegSize = (
unsigned char*)CompressInfo.dest->next_output_byte-output_buffer;
151 jpeg_destroy_compress(&CompressInfo);
159 void InitSource(j_decompress_ptr)
165 boolean FillInputBuffer(j_decompress_ptr)
171 void SkipInputData(j_decompress_ptr CompressInfo,
long NumBytes)
173 CompressInfo->src->next_input_byte += NumBytes;
174 CompressInfo->src->bytes_in_buffer -= NumBytes;
178 void TermSource(j_decompress_ptr)
185 unsigned int& width,
unsigned int& height)
188 struct jpeg_decompress_struct CompressInfo;
189 struct jpeg_error_mgr JErr;
190 struct jpeg_source_mgr SourceManager;
192 CompressInfo.err = jpeg_std_error(&JErr);
193 CompressInfo.err->error_exit = AlternateExit;
194 CompressInfo.err->output_message = AlternatePrint;
195 jpeg_create_decompress(&CompressInfo);
197 SourceManager.next_input_byte = (
unsigned char*)input_buffer.
GetData();
198 SourceManager.bytes_in_buffer = input_buffer.
GetSize();
199 SourceManager.init_source = InitSource;
200 SourceManager.fill_input_buffer = FillInputBuffer;
201 SourceManager.skip_input_data = SkipInputData;
202 SourceManager.resync_to_restart = jpeg_resync_to_restart;
203 SourceManager.term_source = TermSource;
204 CompressInfo.src = &SourceManager;
207 CompressInfo.err->output_message = AlternatePrintNoEcho;
208 if (jpeg_read_header(&CompressInfo,
true) != JPEG_HEADER_OK)
210 jpeg_destroy_decompress(&CompressInfo);
213 CompressInfo.err->output_message = AlternatePrint;
214 CompressInfo.out_color_space = JCS_RGB;
215 width = CompressInfo.image_width;
216 height = CompressInfo.image_height;
217 output_buffer.
Allocate(width*height*3);
218 jpeg_start_decompress(&CompressInfo);
220 while (CompressInfo.output_scanline < height)
222 unsigned char* Row = (
unsigned char*)output_buffer.
GetData()+CompressInfo.output_scanline*width*3;
224 if (jpeg_read_scanlines(&CompressInfo, &Row, 1) == 0)
226 jpeg_finish_decompress(&CompressInfo);
227 jpeg_destroy_decompress(&CompressInfo);
230 for (
unsigned int i = 0; i < width; ++i)
239 jpeg_finish_decompress(&CompressInfo);
240 jpeg_destroy_decompress(&CompressInfo);
247 const char* ImageFormatTypeStrsInit[] = {
"jpeg",
"png",
"tiff",
"ppm"};
250 const MC::StringList ME::ImageFormatTypeStrs(boost::begin(ImageFormatTypeStrsInit),
251 boost::end(ImageFormatTypeStrsInit));
260 _Init(width, height, layers);
274 cvReleaseImage(&
Image);
280 #ifndef __AIBO_BUILD__ 285 MC_WARNING(
"File does not exist: %s", file_name.c_str());
288 IplImage* TempImg = cvLoadImage(file_name.c_str(), -1);
293 RELEASE_IPLIMAGE(
Image);
307 return cvSaveImage(file_name.c_str(),
Image) > 0;
320 const int LayerIndex =
MCBound(0, layer_index,
Image->nChannels-1);
323 cvSetImageCOI(
Image, LayerIndex);
325 cvSetImageCOI(
Image, 0);
332 const int LayerIndex =
MCBound(0, layer_index,
Image->nChannels-1);
336 MC_WARNING(
"Wrong layer dimensions (%dx%d <> %dx%d)",
345 cvSetImageCOI(
Image, LayerIndex);
347 cvSetImageCOI(
Image, 0);
364 RELEASE_IPLIMAGE(
Image);
366 Image = cvCloneImage(other);
368 if (
Image->origin == 1)
378 if (width*height*layer_count != image_data.
GetSize())
380 MC_WARNING(
"No enough image data to be copied (%d != %d)",
381 width*height*layer_count, image_data.
GetSize());
384 _Init(width, height, layer_count);
386 for (
int y = 0; y < height; ++y)
389 int Start2 = width*layer_count*y;
391 memcpy(&
Image->imageData[Start], &image_data.
GetData()[Start2], width*layer_count);
416 if (format == ME::JpegFormat)
423 TempBuffer->GetData(), TempBuffer->GetSize(), 80,
GetLayerCount() == 1);
425 memcpy(JpegData->GetData(), TempBuffer->GetData(), FinalSize);
428 #ifndef __AIBO_BUILD__ 430 std::string FormatStr;
431 std::vector<uchar> Buffer;
433 if (format == ME::PngFormat)
435 if (format == ME::TiffFormat)
437 if (format == ME::PpmFormat)
439 cv::imencode(FormatStr, cv::Mat(
Image,
false), Buffer);
441 memcpy(CompressedData->
GetData(), Buffer.data(), (int)Buffer.size());
442 return CompressedData;
458 if (DecodeJpeg(data, *DecodedData, Width, Height))
463 #ifndef __AIBO_BUILD__ 466 std::vector<char> TempBuffer(data.
GetSize());
468 memcpy(TempBuffer.data(), data.
GetData(), TempBuffer.size());
469 Result = cv::imdecode(TempBuffer, CV_LOAD_IMAGE_UNCHANGED);
470 if (Result.data ==
nullptr)
473 RELEASE_IPLIMAGE(
Image);
474 TempImg = (IplImage)Result;
475 Image = cvCloneImage(&TempImg);
549 _Init(width, height, layer_count);
558 const int Width =
MCMax(width, 1);
559 const int Height =
MCMax(height, 1);
560 IplImage* TempImg = cvCreateImage(cvSize(Width, Height), 8,
Image->nChannels);
562 cvResize(
Image, TempImg, CV_INTER_NN);
563 RELEASE_IPLIMAGE(
Image);
588 cvFlip(
Image,
nullptr, 1);
594 cvFlip(
Image,
nullptr, 0);
605 if (X2-X1 <= 0 || Y2-Y1 <= 0)
608 IplImage* TempImg = cvCreateImage(cvSize(X2-X1, Y2-Y1), 8,
Image->nChannels);
610 cvSetImageROI(
Image, cvRect(X1, Y1, X2-X1, Y2-Y1));
611 cvCopy(
Image, TempImg);
612 cvResetImageROI(
Image);
613 RELEASE_IPLIMAGE(
Image);
636 cvSetImageROI(
Image, cvRect(X, Y, PasteWidth, PasteHeight));
638 cvResetImageROI(
Image);
649 if (X2-X1 <= 0 || Y2-Y1 <= 0)
652 IplImage* TempImg = cvCreateImage(cvSize(X2-X1, Y2-Y1), 8,
Image->nChannels);
654 cvSetImageROI(
Image, cvRect(X1, Y1, X2-X1, Y2-Y1));
655 cvCopy(
Image, TempImg);
656 cvResetImageROI(
Image);
657 RELEASE_IPLIMAGE(other.
Image);
658 other.
Image = TempImg;
668 CvPoint Point1, Point2;
684 CvPoint Point1, Point2;
699 const int Radius =
MCMax(radius, 1);
704 cvCircle(
Image, Point, Radius, CV_RGB(color.
Blue, color.
Green, color.
Red), (fill ? -1 : 1));
712 cv::Mat TempImage(
Image,
false);
714 cv::putText(TempImage, text.c_str(), cv::Point(X, Y), cv::FONT_HERSHEY_TRIPLEX,
715 (double)scale, CV_RGB(color.
Blue, color.
Green, color.
Red));
721 if (iteration_count < 1)
724 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8,
Image->nChannels);
726 cvErode(
Image, TempImg,
nullptr, iteration_count);
727 RELEASE_IPLIMAGE(
Image);
734 if (iteration_count < 1)
737 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8,
Image->nChannels);
739 cvDilate(
Image, TempImg,
nullptr, iteration_count);
740 RELEASE_IPLIMAGE(
Image);
753 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8,
Image->nChannels);
754 int SmoothType = CV_MEDIAN;
756 if (filter_mode == ME::BlurSmoothing)
757 SmoothType = CV_BLUR;
758 if (filter_mode == ME::MedianSmoothing)
759 SmoothType = CV_MEDIAN;
760 if (filter_mode == ME::GaussianSmoothing)
761 SmoothType = CV_GAUSSIAN;
763 cvSmooth(
Image, TempImg, SmoothType, matrix_size, matrix_size, 0);
764 RELEASE_IPLIMAGE(
Image);
771 if (
Image->nChannels > 1)
775 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8,
Image->nChannels);
777 cvCanny(
Image, TempImg, threshold1, threshold2, aperture_size);
778 RELEASE_IPLIMAGE(
Image);
785 if (
Image->nChannels != 1)
789 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), IPL_DEPTH_16S, 1);
791 cvLaplace(
Image, TempImg, 3);
792 cvConvertScale(TempImg,
Image, 1, 0);
793 RELEASE_IPLIMAGE(TempImg);
799 const int LevelCount =
MCBound(1, level_count, 255);
800 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
802 for (
int i =
Image->widthStep*
Image->height-1; i >= 0; --i)
804 ImageData[i] = ImageData[i] / (256 / LevelCount)*(256 / LevelCount);
811 const int ThresholdLimit =
MCBound(1, threshold_limit, 255);
812 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
814 for (
int i =
Image->widthStep*
Image->height-1; i >= 0; --i)
816 if (ImageData[i] < ThresholdLimit)
824 if (
Image->nChannels != 1)
828 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8,
Image->nChannels);
830 cvAdaptiveThreshold(
Image, TempImg, 25,
831 CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 7, -7);
832 RELEASE_IPLIMAGE(
Image);
841 MC_WARNING(
"Image properties are different for masking");
852 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
853 unsigned char* MaskImageData = (
unsigned char*)other.
Image->imageData;
855 for (
int i =
Image->widthStep*
Image->height-1; i >= 0; --i)
857 if (MaskImageData[i] == 0)
865 if (
Image->nChannels == 1)
868 if (mode == ME::RGBtoYUV)
873 if (mode == ME::RGBtoYIQ)
878 if (mode == ME::RGBtorgI)
880 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
881 int WidthStep =
Image->widthStep;
884 for (
int y =
Image->height-1; y >= 0; --y)
886 for (
int x = (
Image->width-1)*3; x >= 0; x -= 3)
892 I = (int)ImageData[RowStart+x]+(
int)ImageData[RowStart+x+1]+(int)ImageData[RowStart+x+2];
893 r = (int)((
float)ImageData[RowStart+x] / I*255);
894 g = (int)((
float)ImageData[RowStart+x+1] / I*255);
895 ImageData[RowStart+x] = (
unsigned char)r;
896 ImageData[RowStart+x+1] = (
unsigned char)g;
897 ImageData[RowStart+x+2] = (
unsigned char)(I / 3);
899 RowStart += WidthStep;
903 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8,
Image->nChannels);
904 int Conversion = CV_RGB2XYZ;
906 if (mode == ME::RGBtoXYZCIED65)
907 Conversion = CV_RGB2XYZ;
908 if (mode == ME::XYZCIED65toRGB)
909 Conversion = CV_XYZ2RGB;
910 if (mode == ME::RGBtoHSV)
911 Conversion = CV_RGB2HSV;
912 if (mode == ME::HSVtoRGB)
913 Conversion = CV_HSV2RGB;
914 if (mode == ME::RGBtoHLS)
915 Conversion = CV_RGB2HLS;
916 if (mode == ME::HLStoRGB)
917 Conversion = CV_HLS2RGB;
918 if (mode == ME::RGBtoCIELab)
919 Conversion = CV_RGB2Lab;
920 if (mode == ME::CIELabtoRGB)
921 Conversion = CV_Lab2RGB;
922 if (mode == ME::RGBtoCIELuv)
923 Conversion = CV_RGB2Luv;
924 if (mode == ME::CIELuvtoRGB)
925 Conversion = CV_Luv2RGB;
927 cvCvtColor(
Image, TempImg, Conversion);
928 RELEASE_IPLIMAGE(
Image);
935 if (
Image->nChannels == 1)
938 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8, 1);
940 cvCvtColor(
Image, TempImg, CV_RGB2GRAY);
941 RELEASE_IPLIMAGE(
Image);
948 if (
Image->nChannels != 1)
951 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8, 3);
953 cvCvtColor(
Image, TempImg, CV_GRAY2RGB);
954 RELEASE_IPLIMAGE(
Image);
961 if (
Image->nChannels != 3)
970 if (
Image->nChannels > 1)
974 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
975 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8, 1);
976 unsigned char* TempImgData = (
unsigned char*)TempImg->imageData;
977 int WidthStep =
Image->widthStep;
978 int WidthStep_2 =
Image->widthStep*2;
981 if (mode == ME::NormalLBP)
983 for (
int i =
Image->widthStep*(
Image->height-2)-1; i >=
Image->widthStep+1; --i)
986 (ImageData[i] <= ImageData[i-
Image->widthStep-1])+
987 ((ImageData[i] <= ImageData[i-
Image->widthStep])*2)+
988 ((ImageData[i] <= ImageData[i-
Image->widthStep+1])*4)+
989 ((ImageData[i] <= ImageData[i-1])*8)+
990 ((ImageData[i] <= ImageData[i+1])*16)+
991 ((ImageData[i] <= ImageData[i+
Image->widthStep-1])*32)+
992 ((ImageData[i] <= ImageData[i+
Image->widthStep])*64)+
993 ((ImageData[i] <= ImageData[i+
Image->widthStep+1])*128);
996 if (mode == ME::SpecialLBP)
998 for (
int i =
Image->widthStep*(
Image->height - 3) - 2; i >=
Image->widthStep*2 + 2; --i)
1000 int CenterPixel = (ImageData[i + 1] + ImageData[i - 1] +
1001 ImageData[i - WidthStep] + ImageData[i + WidthStep])/4;
1002 TempImgData[i] = ((CenterPixel <= (ImageData[i - (WidthStep_2) - 2] +
1003 ImageData[i - (WidthStep_2) - 1] +
1004 ImageData[i - WidthStep - 2] +
1005 ImageData[i - WidthStep - 1])/4)) +
1006 ((CenterPixel <= (ImageData[i - WidthStep] +
1007 ImageData[i - (WidthStep_2)])/2)*2) +
1008 ((CenterPixel <= ((ImageData[i - (WidthStep_2) + 2] +
1009 ImageData[i - (WidthStep_2) + 1] +
1010 ImageData[i - WidthStep + 2] +
1011 ImageData[i - WidthStep + 1])/4))*4) +
1012 ((CenterPixel <= (ImageData[i - 1] +
1013 ImageData[i - 2])/2)*8) +
1014 ((CenterPixel <= (ImageData[i + 1] +
1015 ImageData[i + 2])/2)*16) +
1016 ((CenterPixel <= ((ImageData[i + (WidthStep_2) - 2] +
1017 ImageData[i + (WidthStep_2) - 1] +
1018 ImageData[i + WidthStep - 2] +
1019 ImageData[i + WidthStep - 1])/4))*32) +
1020 ((CenterPixel <= (ImageData[i + WidthStep] +
1021 ImageData[i - WidthStep_2])/2)*64) +
1022 ((CenterPixel <= ((ImageData[i + (WidthStep_2) + 2] +
1023 ImageData[i + (WidthStep_2) + 1] +
1024 ImageData[i + WidthStep + 2] +
1025 ImageData[i + WidthStep + 1])/4))*128);
1028 RELEASE_IPLIMAGE(
Image);
1035 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1037 for (
int i =
Image->height*
Image->widthStep-1; i >= 0; --i)
1039 if (ImageData[i] >= threshold)
1054 MC_WARNING(
"Image properties are different for subtraction.");
1057 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1058 const unsigned char* DstData = (
unsigned char*)other.
Image->imageData;
1059 int WidthStep =
Image->widthStep;
1062 if (mode == ME::NormalSubtraction)
1064 for (
int y =
Image->height-1; y >= 0; --y)
1066 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1068 if (ImageData[RowStart+x]-DstData[RowStart+x] < 0)
1069 ImageData[RowStart+x] = 0;
1071 ImageData[RowStart+x] = ImageData[RowStart+x]-DstData[RowStart+x];
1073 RowStart += WidthStep;
1076 if (mode == ME::AbsolutSubtraction)
1078 for (
int y =
Image->height-1; y >= 0; --y)
1080 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1082 if (ImageData[RowStart+x]-DstData[RowStart+x] < 0)
1083 ImageData[RowStart+x] = -ImageData[RowStart+x]+DstData[RowStart+x];
1085 ImageData[RowStart+x] = ImageData[RowStart+x]-DstData[RowStart+x];
1087 RowStart += WidthStep;
1098 MC_WARNING(
"Image properties are different for multiplication.");
1101 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1102 unsigned char* DstData = (
unsigned char*)other.
Image->imageData;
1104 for (
int i =
Image->height*
Image->widthStep-1; i >= 0; --i)
1106 if (ImageData[i] >= 128 && DstData[i] >= 128)
1108 float Result = (float)ImageData[i] / 128*DstData[i] / 128;
1128 MC_WARNING(
"Image properties are different for addition.");
1131 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1132 unsigned char* SrcData = (
unsigned char*)other.
Image->imageData;
1133 int WidthStep =
Image->widthStep;
1136 if (mode == ME::AverageAddition)
1138 for (
int i =
Image->height*
Image->widthStep-1; i >= 0; --i)
1140 ImageData[i] = (ImageData[i]+SrcData[i]) / 2;
1143 if (mode == ME::UnionAddition)
1145 for (
int i =
Image->height*
Image->widthStep-1; i >= 0; --i)
1147 if (SrcData[i] > ImageData[i])
1148 ImageData[i] = SrcData[i];
1153 for (
int y =
Image->height-1; y >= 0; --y)
1155 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1157 if (SrcData[RowStart+x] > 0)
1158 ImageData[RowStart+x] = SrcData[RowStart+x];
1160 RowStart += WidthStep;
1165 for (
int y =
Image->height-1; y >= 0; --y)
1167 for (
int x =
Image->width*
Image->nChannels-4; x >= 0; x -= 3)
1169 if (SrcData[RowStart+x] > 0 || SrcData[RowStart+x+1] > 0 || SrcData[RowStart+x+2] > 0)
1171 ImageData[RowStart+x] = SrcData[RowStart+x];
1172 ImageData[RowStart+x+1] = SrcData[RowStart+x+1];
1173 ImageData[RowStart+x+2] = SrcData[RowStart+x+2];
1176 RowStart += WidthStep;
1184 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8,
Image->nChannels);
1185 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1186 unsigned char* DstData = (
unsigned char*)TempImg->imageData;
1189 int ywidth =
Image->widthStep;
1191 for (
int y =
Image->height-1; y >= 0; --y)
1192 for (
int x =
Image->width-1; x >= 0; --x)
1194 xy = y*ywidth+x*
Image->nChannels;
1196 for (
int l =
Image->nChannels-1; l >= 0; --l)
1198 if ((ImageData[xy+l] > 0) && (x > 0) && (y > 0) && (x <
Image->width-1) && (y < Image->height-1))
1200 sum = (ImageData[xy-ywidth-
Image->nChannels+l] > 0)+
1201 (ImageData[xy-ywidth+l] > 0)+
1202 (ImageData[xy-ywidth+
Image->nChannels+l] > 0)+
1203 (ImageData[xy-
Image->nChannels+l] > 0)+
1204 (ImageData[xy+
Image->nChannels+l] > 0)+
1205 (ImageData[xy+ywidth-
Image->nChannels+l] > 0)+
1206 (ImageData[xy+ywidth+l] > 0)+
1207 (ImageData[xy+ywidth+
Image->nChannels+l] > 0);
1211 DstData[xy+l] = 255;
1220 RELEASE_IPLIMAGE(
Image);
1230 MC_WARNING(
"Image dimensions or channels are different for area statistics.");
1233 int Difference =
MCBound(0, difference, 100);
1235 unsigned char* OrigImgData = (
unsigned char*)
Image->imageData;
1236 unsigned char* RefImgData = (
unsigned char*)reference.
Image->imageData;
1237 int WidthStep =
Image->widthStep;
1240 for (
int y =
Image->height-1; y >= 0; --y)
1242 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1244 if (abs(OrigImgData[RowStart+x]-RefImgData[RowStart+x]) > Difference)
1247 RowStart += WidthStep;
1249 return (
float)Pixels / ((float)
Image->height*
Image->widthStep*100);
1258 MC_WARNING(
"Image dimensions or channels are different.");
1261 if (
Image->height == 0 ||
Image->widthStep == 0)
1265 unsigned char* OrigImgData = (
unsigned char*)
Image->imageData;
1266 unsigned char* RefImgData = (
unsigned char*)reference.
Image->imageData;
1267 int WidthStep =
Image->widthStep;
1270 for (
int y =
Image->height-1; y >= 0; --y)
1272 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1274 Difference +=
MCAbs(OrigImgData[RowStart+x]-RefImgData[RowStart+x]);
1276 RowStart += WidthStep;
1278 Difference = Difference / (
Image->height*
Image->widthStep);
1288 MC_WARNING(
"Image properties are different for minimum.");
1291 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1292 unsigned char* SecData = (
unsigned char*)other.
Image->imageData;
1293 int WidthStep =
Image->widthStep;
1296 for (
int y =
Image->height-1; y >= 0; --y)
1298 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1300 ImageData[RowStart+x] = (ImageData[RowStart+x] > SecData[RowStart+x] ?
1301 SecData[RowStart+x] : ImageData[RowStart+x]);
1303 RowStart += WidthStep;
1310 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1311 int WidthStep =
Image->widthStep;
1313 int BrightnessLevel = 0;
1315 for (
int y =
Image->height-1; y >= 0; --y)
1317 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1319 BrightnessLevel += (int)ImageData[RowStart+x];
1321 RowStart += WidthStep;
1332 cv::Mat Matrix = cv::getRotationMatrix2D(cv::Point(X, Y), degree, 1.0);
1335 cv::warpAffine(cv::Mat(
Image,
false), cv::Mat(TempImg,
false), Matrix, cv::Size(
GetWidth(),
GetHeight()));
1336 RELEASE_IPLIMAGE(
Image);
1343 return Equal(other, 1);
1357 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1358 unsigned char* RefData = (
unsigned char*)other.
Image->imageData;
1359 int WidthStep =
Image->widthStep;
1362 for (
int y =
Image->height-1; y >= 0; --y)
1364 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1366 if (
MCAbs(ImageData[RowStart+x]-RefData[RowStart+x]) >= max_diff)
1369 RowStart += WidthStep;
1381 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1383 for (
int l = 0; l <
Image->nChannels; l++)
1385 Sum = Sum+(int)ImageData[Y*
Image->width*
Image->nChannels+X*
Image->nChannels+l];
1387 return (
unsigned char)((float)Sum /
Image->nChannels);
1393 return cvSumPixels(
Image);
1401 MC_WARNING(
"Holes can be filled only in binary images.");
1405 CvScalar White = CV_RGB(255, 255, 255);
1406 IplImage* Dst = cvCreateImage(cvGetSize(
Image), 8, 1);
1407 CvMemStorage* Storage = cvCreateMemStorage(0);
1410 cvFindContours(
Image, Storage, &Contour,
sizeof(CvContour),
1411 CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
1414 for (; Contour != 0; Contour = Contour->h_next)
1416 cvDrawContours(Dst, Contour, White, White, 0, CV_FILLED);
1418 cvInRangeS(Dst, White, White,
Image);
1431 unsigned char Table[256];
1433 for (
unsigned int i = 0; i < 256; i++)
1435 Table[i] = (
unsigned char)
MCBound(0, (
int)(pow((
float)i / 255, gamma_level)*255), 255);
1437 unsigned char* ImageData = (
unsigned char*)
Image->imageData;
1438 int WidthStep =
Image->widthStep;
1441 for (
int y =
Image->height-1; y >= 0; --y)
1443 for (
int x =
Image->width*
Image->nChannels-1; x >= 0; --x)
1445 ImageData[RowStart+x] = Table[ImageData[RowStart+x]];
1447 RowStart += WidthStep;
1459 RELEASE_IPLIMAGE(
Image);
1469 RELEASE_IPLIMAGE(
Image);
1471 if (width < 1 || height < 1 || (layer_count != 1 && layer_count != 3))
1473 Image = cvCreateImage(cvSize(16, 16), 8, 1);
1476 Image = cvCreateImage(cvSize(width, height), 8, layer_count);
1482 if (
Image->nChannels != 3)
1484 MC_WARNING(
"Image must have three color channels (%d != 3)",
Image->nChannels);
1487 if (mode != ME::RGBtoYUV && mode != ME::RGBtoYIQ)
1489 MC_WARNING(
"Color space conversion is not supported (%d)", (
int)mode);
1492 float TransformMatrix[3][3];
1493 IplImage* TempImg = cvCreateImage(cvSize(
Image->width,
Image->height), 8,
Image->nChannels);
1495 for (
int i = 0; i < 3; i++)
1496 for (
int i1 = 0; i1 < 3; i1++)
1498 if (mode == ME::RGBtoYUV)
1499 TransformMatrix[i][i1] = RGBtoYUVMatrix[i][i1];
1500 if (mode == ME::RGBtoYIQ)
1501 TransformMatrix[i][i1] = RGBtoYIQMatrix[i][i1];
1510 if (mode == ME::RGBtoYUV)
1519 if (mode == ME::RGBtoYIQ)
1528 unsigned char* SrcData = (
unsigned char*)
Image->imageData;
1529 unsigned char* DstData = (
unsigned char*)TempImg->imageData;
1531 for (
int i =
Image->widthStep*
Image->height-1; i >= 0; i-=3)
1533 float x = (float)SrcData[i]*TransformMatrix[0][0]+
1534 (
float)SrcData[i+1]*TransformMatrix[0][1]+
1535 (float)SrcData[i+2]*TransformMatrix[0][2];
1536 float y = (float)SrcData[i]*TransformMatrix[1][0]+
1537 (
float)SrcData[i+1]*TransformMatrix[1][1]+
1538 (float)SrcData[i+2]*TransformMatrix[1][2];
1539 float z = (float)SrcData[i]*TransformMatrix[2][0]+
1540 (
float)SrcData[i+1]*TransformMatrix[2][1]+
1541 (float)SrcData[i+2]*TransformMatrix[2][2];
1543 x = xmax-xmin != 0.0 ? 255.0 : (x-xmin) / (xmax-xmin)*255.0;
1544 y = ymax-ymin != 0.0 ? 255.0 : (y-xmin) / (ymax-ymin)*255.0;
1545 z = zmax-zmin != 0.0 ? 255.0 : (z-xmin) / (zmax-zmin)*255.0;
1547 DstData[i] = (
unsigned char)
MCBound(0, (
int)x, 255);
1548 DstData[i+1] = (
unsigned char)
MCBound(0, (
int)y, 255);
1549 DstData[i+2] = (
unsigned char)
MCBound(0, (
int)z, 255);
1551 RELEASE_IPLIMAGE(
Image);
int GetWidth() const
Get the image width.
void Threshold(int threshold_limit)
Threshold function.
void _Init(int width, int height, int layer_count)
Initialize the image data.
void Addition(MEImage &other, ME::AdditionType mode)
Addition of an image and the internal picture.
void PasteImageInside(int x, int y, MEImage &other)
Copy image data from an other picture inside.
bool operator!=(const MEImage &other)
Inequality operator.
void ResizeScaleX(int width)
Resize image with new width.
MEImage()
Class constructor.
void DrawRectangle(int x0, int y0, int x1, int y1, const MEColor &color, bool fill=true)
Draw a rectangle.
int GetLayerCount() const
Get the image layer count.
void SetIplImage(const IplImage *other)
Set the internal IplImage.
bool SaveToFile(const std::string &file_name) const
Save an image to file.
void DrawCircle(int x, int y, int radius, const MEColor &color, bool fill=true)
Draw a circle.
void CopyImagePart(int x1, int y1, int x2, int y2, MEImage &other)
Copy an image part to an other picture.
void Crop(int x1, int y1, int x2, int y2)
Crop image.
MCBinaryData * Compress(ME::ImageFormatType format=ME::JpegFormat) const
Compress the image data.
void Binarize(int threshold)
Binarize an image.
void Smooth()
Smooth function with 3x3 median filter.
float GetRatio() const
Get image ratio.
bool LoadFromFile(const std::string &file_name)
Load an image from a file.
float AverageBrightnessLevel() const
Calculate average brightness level.
#define MC_WARNING(...)
Warning macro.
void Mask(MEImage &other)
Mask with a threshold image.
const T & MCBound(const T &min, const T &value, const T &max)
Check a value bound according to a range.
T MCAbs(const T &value)
Calculate absolute value.
void ResizeScaleY(int height)
Resize image with new height.
bool _Copy(const MEImage &other)
Copy image data.
void ConvertBGRToRGB()
Change the red and blue components of every pixel.
MEImage & operator=(const MEImage &other)
Copy assignment operator.
void Rotate(int x, int y, float degree)
Rotate the image.
void Erode(int iteration_count)
Erode function.
void Allocate(int size)
Allocate a certain data size.
void MirrorVertical()
Reverse image in vertical direction.
void ComputeColorSpace(ME::ColorSpaceType mode)
Compute an image to a different color space.
unsigned char GrayscalePixel(int x, int y) const
Get the grayscale value of a pixel.
void Quantize(int level_count)
Image quantisation.
MCBinaryData * ExportRawImageData() const
Export the raw image data.
void SetLayer(const MEImage &new_layer, int layer_index)
Copy a new layer to the image.
void Clear()
Clear image with zeroes.
~MEImage()
Destructor of class.
int GetHeight() const
Get the image height.
void Canny(double threshold1=800, double threshold2=1100, int aperture_size=5)
Canny function.
int GetRowWidth() const
Get the image row width.
int GetImageDataSize() const
Get the number of the image pixel data.
int AverageDifference(MEImage &reference) const
Calculate an average difference between two images.
void LBP(ME::LBPType mode=ME::SpecialLBP)
Compute an LBP filter over the image.
bool MCFileExists(const std::string &file_name)
Check whether a file exists.
unsigned char Blue
Blue component.
void ConvertToGrayscale()
Convert to grayscale.
bool Equal(const MEImage &other) const
Compare to an other image.
void Resize(int width, int height)
Resize image.
void MirrorHorizontal()
Reverse image in horizontal direction.
void ConvertToColorSpace(ME::ColorSpaceType transformation)
Convert into a new color space.
unsigned char Red
Red component.
unsigned char * GetData() const
Get direct access to the binary data.
void GammaCorrection(float gamma_level)
Gamma correction.
void Dilate(int iteration_count)
Dilate function.
void Multiple(MEImage &other)
Multiple an image with the internal picture.
void AdaptiveThreshold()
Adaptive threshold function.
const IplImage * GetIplImage() const
Get access to the internal OpenCV image data.
void SmoothAdvanced(ME::SmoothType filter_mode, int matrix_size)
Advanced smooth function.
void Laplace()
Laplace function.
const T MCMax(const U &container)
Get the maximal value of a container.
void EliminateSinglePixels()
Eliminate the single pixels from a binary image.
float DifferenceAreas(MEImage &reference, int difference) const
Calculate an area difference feature between two images.
IplImage * Image
Image data in OpenCV format.
bool Decompress(const MCBinaryData &data)
Decompress image data.
void Realloc(int width, int height)
Reallocate image data by keeping the layer count.
void FillHoles()
Fill holes.
void DrawText(int x, int y, const std::string &text, float scale, const MEColor &color)
Draw a text.
void ConvertToRGB()
Convert to RGB.
bool operator==(const MEImage &other)
Equality operator.
unsigned char Green
Green component.
void SetRawImageData(const MCBinaryData &image_data, int width, int height, int layer_count)
Set the image data.
void Subtract(const MEImage &other, ME::SubtractionType mode)
Subtract an image.
void Minimum(MEImage &other)
Minimum between two images.
unsigned int GetWhitePixelCount()
Get white pixel count.
void DrawLine(int x0, int y0, int x1, int y1, const MEColor &color)
Draw a line.
MEImage * GetLayer(int layer_index) const
Get an image layer.
int GetSize() const
Get binary data size.