2using System.Collections.Generic;
25 if (!bIsDataRealOverride.HasValue)
44 public static Datum GetImageDataD(Bitmap bmp,
int nChannels,
bool bDataIsReal,
int nLabel,
bool bUseLockBitmap =
true,
int[] rgFocusMap =
null)
46 if (nChannels != 1 && nChannels != 3)
47 throw new Exception(
"Images only support either 1 or 3 channels.");
49 List<byte>[] rgrgByteData =
new List<byte>[nChannels];
50 List<double>[] rgrgRealData =
new List<double>[nChannels];
52 for (
int i = 0; i < nChannels; i++)
54 rgrgByteData[i] =
new List<byte>();
55 rgrgRealData[i] =
new List<double>();
58 if (bmp.Width >= bmp.Height && bUseLockBitmap)
65 for (
int y = 0; y < bmp1.
Height; y++)
67 for (
int x = 0; x < bmp1.
Width; x++)
71 if (rgFocusMap !=
null)
73 int nIdx = y * bmp1.
Width + x;
74 nFocus = rgFocusMap[nIdx];
77 Color clr = (nFocus == 1) ? bmp1.
GetPixel(x, y) : Color.Black;
82 rgrgRealData[0].Add(clr.ToArgb());
84 rgrgByteData[0].Add((
byte)((clr.R * 0.3) + (clr.G * 0.59) + (clr.B * 0.11)));
90 rgrgRealData[0].Add(clr.R);
91 rgrgRealData[1].Add(clr.G);
92 rgrgRealData[2].Add(clr.B);
96 rgrgByteData[0].Add(clr.R);
97 rgrgByteData[1].Add(clr.G);
98 rgrgByteData[2].Add(clr.B);
104 catch (Exception excpt)
116 for (
int y = 0; y < bmp.Height; y++)
118 for (
int x = 0; x < bmp.Width; x++)
122 if (rgFocusMap !=
null)
124 int nIdx = y * bmp.Width + x;
125 nFocus = rgFocusMap[nIdx];
128 Color clr = (nFocus == 1) ? bmp.GetPixel(x, y) : Color.Black;
133 rgrgRealData[0].Add(clr.ToArgb());
135 rgrgByteData[0].Add((
byte)((clr.R * 0.3) + (clr.G * 0.59) + (clr.B * 0.11)));
141 rgrgRealData[0].Add(clr.R);
142 rgrgRealData[1].Add(clr.G);
143 rgrgRealData[2].Add(clr.B);
147 rgrgByteData[0].Add(clr.R);
148 rgrgByteData[1].Add(clr.G);
149 rgrgByteData[2].Add(clr.B);
156 List<byte> rgByteData =
new List<byte>();
157 List<double> rgRealData =
new List<double>();
159 for (
int i = 0; i < nChannels; i++)
161 rgByteData.AddRange(rgrgByteData[i]);
162 rgRealData.AddRange(rgrgRealData[i]);
166 return new Datum(
true, nChannels, bmp.Width, bmp.Height, nLabel, DateTime.MinValue,
new List<double>(rgRealData), 0,
false, -1);
168 return new Datum(
false, nChannels, bmp.Width, bmp.Height, nLabel, DateTime.MinValue,
new List<byte>(rgByteData), 0,
false, -1);
181 public static Datum GetImageDataF(Bitmap bmp,
int nChannels,
bool bDataIsReal,
int nLabel,
bool bUseLockBitmap =
true,
int[] rgFocusMap =
null)
183 if (nChannels != 1 && nChannels != 3)
184 throw new Exception(
"Images only support either 1 or 3 channels.");
186 List<byte>[] rgrgByteData =
new List<byte>[nChannels];
187 List<float>[] rgrgRealData =
new List<float>[nChannels];
189 for (
int i = 0; i < nChannels; i++)
191 rgrgByteData[i] =
new List<byte>();
192 rgrgRealData[i] =
new List<float>();
195 if (bmp.Width >= bmp.Height && bUseLockBitmap)
202 for (
int y = 0; y < bmp1.
Height; y++)
204 for (
int x = 0; x < bmp1.
Width; x++)
208 if (rgFocusMap !=
null)
210 int nIdx = y * bmp1.
Width + x;
211 nFocus = rgFocusMap[nIdx];
214 Color clr = (nFocus == 1) ? bmp1.
GetPixel(x, y) : Color.Black;
219 rgrgRealData[0].Add(clr.ToArgb());
221 rgrgByteData[0].Add((
byte)((clr.R * 0.3) + (clr.G * 0.59) + (clr.B * 0.11)));
227 rgrgRealData[0].Add(clr.R);
228 rgrgRealData[1].Add(clr.G);
229 rgrgRealData[2].Add(clr.B);
233 rgrgByteData[0].Add(clr.R);
234 rgrgByteData[1].Add(clr.G);
235 rgrgByteData[2].Add(clr.B);
241 catch (Exception excpt)
253 for (
int y = 0; y < bmp.Height; y++)
255 for (
int x = 0; x < bmp.Width; x++)
259 if (rgFocusMap !=
null)
261 int nIdx = y * bmp.Width + x;
262 nFocus = rgFocusMap[nIdx];
265 Color clr = (nFocus == 1) ? bmp.GetPixel(x, y) : Color.Black;
270 rgrgRealData[0].Add(clr.ToArgb());
272 rgrgByteData[0].Add((
byte)((clr.R * 0.3) + (clr.G * 0.59) + (clr.B * 0.11)));
278 rgrgRealData[0].Add(clr.R);
279 rgrgRealData[1].Add(clr.G);
280 rgrgRealData[2].Add(clr.B);
284 rgrgByteData[0].Add(clr.R);
285 rgrgByteData[1].Add(clr.G);
286 rgrgByteData[2].Add(clr.B);
293 List<byte> rgByteData =
new List<byte>();
294 List<float> rgRealData =
new List<float>();
296 for (
int i = 0; i < nChannels; i++)
298 rgByteData.AddRange(rgrgByteData[i]);
299 rgRealData.AddRange(rgrgRealData[i]);
303 return new Datum(
true, nChannels, bmp.Width, bmp.Height, nLabel, DateTime.MinValue,
new List<float>(rgRealData), 0,
false, -1);
305 return new Datum(
false, nChannels, bmp.Width, bmp.Height, nLabel, DateTime.MinValue,
new List<byte>(rgByteData), 0,
false, -1);
319 public static Datum GetImageData<T>(T[] rgData,
int nChannels,
int nHeight,
int nWidth,
bool bDataIsReal,
int nStartIdx = 0,
int nCount = -1)
322 nCount = rgData.Length;
324 if (nChannels != 1 && nChannels != 3)
325 throw new Exception(
"Images only support either 1 or 3 channels.");
329 if (typeof(T) == typeof(
double))
331 double[] rgRealData = (
double[])Convert.ChangeType(rgData, typeof(
double[]));
332 return new Datum(
true, nChannels, nWidth, nHeight, 0, DateTime.MinValue,
new List<double>(rgRealData), 0,
false, -1);
334 else if (typeof(T) == typeof(
float))
336 float[] rgRealData = (
float[])Convert.ChangeType(rgData, typeof(
float[]));
337 return new Datum(
true, nChannels, nWidth, nHeight, 0, DateTime.MinValue,
new List<float>(rgRealData), 0,
false, -1);
341 throw new Exception(
"Unsupported type '" + typeof(T).ToString() +
" - only 'double' and 'float' are supported.");
346 List<byte> rgByteData =
new List<byte>();
347 float[] rgDataF =
Utility.ConvertVecF<T>(rgData);
349 for (
int i = nStartIdx; i < nStartIdx + nCount; i++)
351 float fVal = rgDataF[i];
353 if (
float.IsInfinity(fVal) ||
float.IsNaN(fVal))
356 rgByteData.Add((
byte)fVal);
359 return new Datum(
false, nChannels, nWidth, nHeight, 0, DateTime.MinValue,
new List<byte>(rgByteData), 0,
false, -1);
374 throw new Exception(
"Standard images only support either 1 or 3 channels.");
377 List<byte>[] rgrgByteData =
new List<byte>[d.
Channels];
378 List<double>[] rgrgRealData =
new List<double>[d.
Channels];
386 for (
int i = 0; i < d.
Channels; i++)
388 List<byte> rgByteData =
new List<byte>();
389 List<double> rgRealData =
new List<double>();
392 if (rgClrOrder !=
null)
393 nChIdx = rgClrOrder[i];
397 for (
int j = 0; j < nCount; j++)
400 dfMin = Math.Min(dfMin, dfVal);
401 dfMax = Math.Max(dfMax, dfVal);
402 rgRealData.Add(dfVal);
405 rgrgRealData[nChIdx] = rgRealData;
409 for (
int j = 0; j < nCount; j++)
411 rgByteData.Add(d.
ByteData[nOffset + j]);
414 rgrgByteData[nChIdx] = rgByteData;
426 for (
int y = 0; y < bmp1.
Height; y++)
428 for (
int x = 0; x < bmp1.
Width; x++)
431 int nIdx = (y * bmp1.
Width) + x;
437 if (dfMin >= 0 && dfMax <= 1.0)
439 int nG = (int)(rgrgRealData[0][nIdx] * 255.0);
445 clr = Color.FromArgb(nG, nG, nG);
449 clr = Color.FromArgb((
int)rgrgRealData[0][nIdx]);
453 clr = clrMap.GetColor(clr.ToArgb());
457 clr = Color.FromArgb((
int)rgrgByteData[0][nIdx], (int)rgrgByteData[0][nIdx], (
int)rgrgByteData[0][nIdx]);
464 int nR = (nChannel == 0) ? (
int)rgrgRealData[0][nIdx] : 0;
465 int nG = (nChannel == 1) ? (
int)rgrgRealData[1][nIdx] : 0;
466 int nB = (nChannel == 2) ? (
int)rgrgRealData[2][nIdx] : 0;
468 clr = Color.FromArgb(nR, nG, nB);
471 clr = clrMap.GetColor(clr.ToArgb());
475 int nR = (nChannel == 0) ? (
int)rgrgByteData[0][nIdx] : 0;
476 int nG = (nChannel == 1) ? (
int)rgrgByteData[1][nIdx] : 0;
477 int nB = (nChannel == 2) ? (
int)rgrgByteData[2][nIdx] : 0;
479 clr = Color.FromArgb(nR, nG, nB);
487 catch (Exception excpt)
509 throw new Exception(
"Standard images only support either 1 or 3 channels.");
512 List<byte>[] rgrgByteData =
new List<byte>[d.
Channels];
513 List<double>[] rgrgRealData =
new List<double>[d.
Channels];
521 for (
int i = 0; i < d.
Channels; i++)
523 List<byte> rgByteData =
new List<byte>();
524 List<double> rgRealData =
new List<double>();
527 if (rgClrOrder !=
null)
528 nChIdx = rgClrOrder[i];
532 for (
int j = 0; j < nCount; j++)
535 dfMin = Math.Min(dfMin, dfVal);
536 dfMax = Math.Max(dfMax, dfVal);
537 rgRealData.Add(dfVal);
540 rgrgRealData[nChIdx] = rgRealData;
544 for (
int j = 0; j < nCount; j++)
546 rgByteData.Add(d.
ByteData[nOffset + j]);
549 rgrgByteData[nChIdx] = rgByteData;
561 for (
int y = 0; y < bmp1.
Height; y++)
563 for (
int x = 0; x < bmp1.
Width; x++)
566 int nIdx = (y * bmp1.
Width) + x;
572 if (dfMin >= 0 && dfMax <= 1.0)
574 int nG = clip((
int)(rgrgRealData[0][nIdx] * 255.0), 0, 255);
575 clr = Color.FromArgb(nG, nG, nG);
579 clr = Color.FromArgb((
int)rgrgRealData[0][nIdx]);
583 clr = clrMap.GetColor(clr.ToArgb());
587 int nR = clip((
int)rgrgByteData[0][nIdx], 0, 255);
588 int nG = clip((
int)rgrgByteData[0][nIdx], 0, 255);
589 int nB = clip((
int)rgrgByteData[0][nIdx], 0, 255);
591 clr = Color.FromArgb(nR, nG, nB);
598 int nR = clip((
int)rgrgRealData[0][nIdx], 0, 255);
599 int nG = clip((
int)rgrgRealData[1][nIdx], 0, 255);
600 int nB = clip((
int)rgrgRealData[2][nIdx], 0, 255);
602 clr = Color.FromArgb(nR, nG, nB);
605 clr = clrMap.GetColor(clr.ToArgb());
609 int nR = clip((
int)rgrgByteData[0][nIdx], 0, 255);
610 int nG = clip((
int)rgrgByteData[1][nIdx], 0, 255);
611 int nB = clip((
int)rgrgByteData[2][nIdx], 0, 255);
613 clr = Color.FromArgb(nR, nG, nB);
621 catch (Exception excpt)
633 private static int clip(
int n,
int nMin,
int nMax)
653 Bitmap bmp =
new Bitmap(sz.Width, sz.Height);
654 int nSize = (int)Math.Ceiling(Math.Sqrt(rg.Count));
657 float fIncX = (float)sz.Width / (
float)nSize;
658 float fIncY = (float)sz.Height / (
float)nSize;
660 using (Graphics g = Graphics.FromImage(bmp))
662 g.FillRectangle(Brushes.Black,
new RectangleF(0, 0, bmp.Width, bmp.Height));
664 for (
int i=0; i<rg.Count; i++)
666 Brush br =
new SolidBrush(clrMap.
GetColor(rg[i].Score));
667 g.FillRectangle(br, fX, fY, fIncX, fIncY);
683 private static double getColorAverage(Bitmap bmp,
int nRow)
685 double dfColorTotal = 0;
687 for (
int x = 0; x < bmp.Width; x++)
689 Color clr = bmp.GetPixel(x, nRow);
691 dfColorTotal += clr.R;
692 dfColorTotal += clr.B;
693 dfColorTotal += clr.G;
696 return dfColorTotal / bmp.Width;
699 private static void offsetInward(Bitmap bmp, ref
int nYBottom, ref
int nYTop,
int nSegmentHeight)
704 while (nYBottom - nYTop > nSegmentHeight)
706 dfAve1 = getColorAverage(bmp, nYBottom - 1);
711 if (nYBottom - nYTop > nSegmentHeight)
713 dfAve2 = getColorAverage(bmp, nYTop);
715 if (dfAve2 == 0 || dfAve2 < dfAve1)
720 if (dfAve1 > 0 && dfAve2 > 0)
726 private static double[] getImageData(Bitmap bmp,
int nYBottom,
int nYTop,
int nSegmentHeight)
728 double[] rgrgData =
new double[nSegmentHeight * bmp.Width];
730 offsetInward(bmp, ref nYBottom, ref nYTop, nSegmentHeight);
732 for (
int y = 0; y < nSegmentHeight; y++)
734 for (
int x = 0; x < bmp.Width; x++)
736 Color clr = bmp.GetPixel(x, y + nYTop);
738 int nDataIdx = (y * bmp.Width) + x;
742 int nColor = (nR << 16) + (nG << 8) + nB;
743 double dfClr = (double)nColor / (
double)0xFFFFFF;
745 rgrgData[nDataIdx] = dfClr;
760 if (
string.IsNullOrEmpty(strImgFile) || !File.Exists(strImgFile))
763 Bitmap bmpFocus =
null;
765 bmpFocus =
new Bitmap(strImgFile);
766 int[] rgnFocusMap =
new int[bmpFocus.Width * bmpFocus.Height];
768 for (
int y = 0; y < bmpFocus.Height; y++)
770 for (
int x = 0; x < bmpFocus.Width; x++)
772 Color clr = bmpFocus.GetPixel(x, y);
773 if (clr.R != 0 || clr.G != 0 || clr.R != 0)
774 rgnFocusMap[y * bmpFocus.Width + x] = 1;
The ColorMapper maps a value within a number range, to a Color within a color scheme.
Color GetColor(double dfVal)
Find the color using a binary search algorithm.
The Datum class is a simple wrapper to the SimpleDatum class to ensure compatibility with the origina...
The ImageData class is a helper class used to convert between Datum, other raw data,...
static int[] LoadFocusMap(string strImgFile)
Load a black/white image as a focus map where any area not colored black is attributed focus....
static Datum GetImageData< T >(T[] rgData, int nChannels, int nHeight, int nWidth, bool bDataIsReal, int nStartIdx=0, int nCount=-1)
The GetImageData function converts an array of type 'T' into a Datum.
static Datum GetImageData(Bitmap bmp, SimpleDatum sd, bool? bIsDataRealOverride=null, int[] rgFocusMap=null)
The GetImageData function converts a Bitmap into a Datum.
static Bitmap GetImage(SimpleDatum d, ColorMapper clrMap=null, List< int > rgClrOrder=null)
Converts a SimplDatum (or Datum) into an image, optionally using a ColorMapper.
static Bitmap GetImageAtChannel(SimpleDatum d, int nChannel, ColorMapper clrMap=null, List< int > rgClrOrder=null)
Converts a SimplDatum (or Datum) into an image, optionally using a ColorMapper.
static Datum GetImageDataF(Bitmap bmp, int nChannels, bool bDataIsReal, int nLabel, bool bUseLockBitmap=true, int[] rgFocusMap=null)
The GetImageDataF function converts a Bitmap into a Datum using the float type for real data.
static Bitmap GetImage(List< Result > rg, Size sz, ColorMapper clrMap)
Converts a list of KeyValuePairs into an image using a ColorMapper.
static Datum GetImageDataD(Bitmap bmp, int nChannels, bool bDataIsReal, int nLabel, bool bUseLockBitmap=true, int[] rgFocusMap=null)
The GetImageDataD function converts a Bitmap into a Datum using the double type for real data.
The LockBitmap class provides very efficient SetPixel and GetPixel functionality of a bitmap by using...
Color GetPixel(int x, int y)
Get the color of the specified pixel
void SetPixel(int x, int y, Color color)
Set the color of the specified pixel
void UnlockBits()
Unlock bitmap data, releasing its underlying data.
int Width
Returns the width of the bitmap.
int Height
Returns the height of the bitmap.
void LockBits()
Lock bitmap data to access its underlying raw data.
The SimpleDatum class holds a data input within host memory.
bool HasRealData
Returns true if either the RealDataD or RealDataF are non null and have length > 0.
int Channels
Return the number of channels of the data.
bool IsRealData
Returns whether or not the data contains real numbers or byte data.
int Width
Return the width of the data.
double GetDataAtD(int nIdx)
Returns the item at a specified index in the double type.
byte[] ByteData
Return the byte data. This field is valid when IsRealData = false.
int Height
Return the height of the data.
double[] RealDataD
Return the double data. This field is valid when IsRealData = true.
int Label
Return the known label of the data.
The Utility class provides general utility funtions.
The MyCaffe.basecode contains all generic types used throughout MyCaffe.