/// <summary>
		/// Adjust contrast in RGB colour space.
		/// </summary>
		/// <param name="bitmap">The bitmap.</param>
		public static Bitmap Contrast(this Bitmap bitmap) {
			if ((bitmap = bitmap.Channel()) != null) {
				var contrastCorrection = new ContrastCorrection();
				contrastCorrection.ApplyInPlace(bitmap);
			}
			return bitmap;
		}
 /// <summary>
 /// Linear correction in RGB colour space.
 /// </summary>
 /// <param name="bitmap">The bitmap.</param>
 public static Bitmap Colour(this Bitmap bitmap) {
     if ((bitmap = bitmap.Channel()) == null) return null;
     var imageStatistics = new ImageStatistics(bitmap);
     var levelsLinear = new LevelsLinear {
         InRed = imageStatistics.Red.GetRange(0.995),
         InGreen = imageStatistics.Green.GetRange(0.995),
         InBlue = imageStatistics.Blue.GetRange(0.995)
     };
     levelsLinear.ApplyInPlace(bitmap);
     return bitmap;
 }
 /// <summary>
 /// Adjust contrast in RGB colour space.
 /// </summary>
 public static Bitmap Contrast(this Bitmap Bitmap)
 {
     // Convert grayscale to RGB colour space.
     if ((Bitmap = Bitmap.Channel()) != null) {
         // Initialize a new instance of the ContrastCorrection class.
         var ContrastCorrection = new ContrastCorrection();
         // Apply the filter to the image.
         ContrastCorrection.ApplyInPlace(Bitmap);
     }
     // Return the bitmap.
     return Bitmap;
 }
		/// <summary>
		/// Crop the image to remove a textual addition.
		/// </summary>
		/// <param name="bitmap">The bitmap.</param>
		public static Bitmap Crop(this Bitmap bitmap) {
			if ((bitmap = bitmap.Channel()) != null) {
				var channel = new int[3];
				var incision = -1;
				var firstBlack = -1;
				var previousBlack = -1;
				for (var line = 0; line < 80 && line < bitmap.Height; line++) {
					var hasBlack = false;
					var y = bitmap.Height - line - 1;
					channel[0] = channel[1] = channel[2] = 0;
					for (var x = 0; x < bitmap.Width; x++) {
						var color = bitmap.GetPixel(x, y);
						if (color.R < 45 && color.G < 45 && color.B < 45) {
							hasBlack = true;
							break;
						}
						channel[0] += color.R;
						channel[1] += color.G;
						channel[2] += color.B;
					}
					if (hasBlack) {
						if (firstBlack == -1 && (firstBlack = line > 5 ? 5 : line) == 0) {
							break;
						}
						previousBlack = line;
					} else if (firstBlack != -1 && previousBlack != -1) {
						channel[0] /= bitmap.Width;
						channel[1] /= bitmap.Width;
						channel[2] /= bitmap.Width;
						if (channel[0] >= 245 && channel[1] >= 245 && channel[2] >= 245) {
							incision = previousBlack + firstBlack;
						}
					}
				}
				if (incision != -1) {
					var rectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height - incision);
					var result = bitmap.Clone(rectangle, bitmap.PixelFormat);
					bitmap.Dispose();
					return result;
				}
			}
			return bitmap;
		}
 /// <summary>
 /// Implements an artifact-detection algorithm
 /// </summary>
 public static bool HasMotionArtifact(this IEnumerable<EEGDataEntry> trial,
     double round1Alpha = 0.025,
     double round1Threshold = 40.0,
     double round2Alpha = 0.5,
     double round2Threshold = 40.0,
     Channel channel = Channel.AF3,
     bool useMirror = false)
 {
     var channelData = trial.Channel(channel);
     //THROWING EXCEPTION: IT SAYS THE SEQUENCE IS EMPTY
     double avg = channelData.Average();
     if (channelData.MovingAverages(round1Alpha).Select(ma => Math.Abs(ma - avg)).Max() > round1Threshold)
         return true;
     if (channelData.ParallelTo(channelData.MovingAverages(round1Alpha)).Select(d => d.Item1 - d.Item2).MovingAverages(round2Alpha).Max() > round2Threshold)
         return true;
     return useMirror
         ? trial.HasMotionArtifact(round1Alpha, round1Threshold, round2Alpha, round2Threshold, channel.Mirror(), false)
         : false;
 }
 /// <summary>
 /// Linear correction in RGB colour space.
 /// </summary>
 /// <param name="Bitmap">The bitmap.</param>
 public static Bitmap Colour(this Bitmap Bitmap)
 {
     // Convert grayscale to RGB colour space.
     if ((Bitmap = Bitmap.Channel()) != null) {
         // Initialize a new instance of the LevelsLinear class.
         ImageStatistics ImageStatistics = new ImageStatistics(Bitmap);
         // Initialize a new instance of the LevelsLinear class.
         LevelsLinear LevelsLinear = new LevelsLinear {
             // Retrieve and set the range around the median for the red-channel.
             InRed = ImageStatistics.Red.GetRange(0.995),
             // Retrieve and set the range around the median for the green-channel.
             InGreen = ImageStatistics.Green.GetRange(0.995),
             // Retrieve and set the range around the median for the blue-channel.
             InBlue = ImageStatistics.Blue.GetRange(0.995)
         };
         // Apply the filter to the image.
         LevelsLinear.ApplyInPlace(Bitmap);
     }
     // Return the bitmap.
     return Bitmap;
 }
		/// <summary>
		/// Sharpen using a gaussian sharpen filter.
		/// </summary>
		public static Bitmap Sharpen(this Bitmap bitmap) {
			if ((bitmap = bitmap.Channel()) != null) {
				var gaussianSharpen = new GaussianSharpen();
				gaussianSharpen.ApplyInPlace(bitmap);
			}
			return bitmap;
		}
		/// <summary>
		/// Reduce noise using conservative smoothing.
		/// </summary>
		/// <param name="bitmap">The bitmap.</param>
		public static Bitmap Noise(this Bitmap bitmap) {
			if ((bitmap = bitmap.Channel()) != null) {
				var conservativeSmoothing = new ConservativeSmoothing();
				conservativeSmoothing.ApplyInPlace(bitmap);
			}
			return bitmap;
		}
		/// <summary>
		/// Convert RGB colour space to grayscale when applicable.
		/// </summary>
		/// <param name="bitmap">The bitmap.</param>
		public static Bitmap Grayscale(this Bitmap bitmap) {
			if ((bitmap = bitmap.Channel()) != null) {
				var imageStatisticsHSL = new ImageStatisticsHSL(bitmap);
				if (imageStatisticsHSL.Saturation.Max == 0) {
					var grayscale = new Grayscale(0.2125, 0.7154, 0.0721);
					var result = grayscale.Apply(bitmap);
					bitmap.Dispose();
					return result;
				}
			}
			return bitmap;
		}
 /// <summary>
 /// Crop the image to remove a textual addition.
 /// </summary>
 /// <param name="Bitmap">The bitmap.</param>
 public static Bitmap Crop(this Bitmap Bitmap)
 {
     // Convert grayscale to RGB colour space.
     if ((Bitmap = Bitmap.Channel()) != null) {
         // Initialize each channel.
         int[] Channel = new int[3];
         // Initialize the incision line.
         int Incision = -1;
         // Initialize the first black line.
         int FirstBlack = -1;
         // Initialize the previous black line.
         int PreviousBlack = -1;
         // Iterate through each line until the maximum incision height.
         for (int Line = 0; Line < 80 && Line < Bitmap.Height; Line++) {
             // Initialize the boolean indicating whether the line has black.
             bool HasBlack = false;
             // Initialize the line.
             int Y = Bitmap.Height - Line - 1;
             // Reset each channel.
             Channel[0] = Channel[1] = Channel[2] = 0;
             // Iterate through each pixel on the line.
             for (int X = 0; X < Bitmap.Width; X++) {
                 // Retrieve the color for the pixel.
                 Color Color = Bitmap.GetPixel(X, Y);
                 // Check if the color is considered to be black.
                 if (Color.R < 45 && Color.G < 45 && Color.B < 45) {
                     // Set the status indicating this line has black.
                     HasBlack = true;
                     // Break from the iteration.
                     break;
                 }
                 // Add the red component to the red channel.
                 Channel[0] += Color.R;
                 // Add the green component to the red channel.
                 Channel[1] += Color.G;
                 // Add the blue component to the red channel.
                 Channel[2] += Color.B;
             }
             // Check if the line has black.
             if (HasBlack) {
                 // Check if the first black line has not been set.
                 if (FirstBlack == -1 && (FirstBlack = Line > 5 ? 5 : Line) == 0) {
                     // Break when the first line is black.
                     break;
                 }
                 // Set the previous black line.
                 PreviousBlack = Line;
             } else if (FirstBlack != -1 && PreviousBlack != -1) {
                 // Divide the red color channel to attain the median.
                 Channel[0] /= Bitmap.Width;
                 // Divide the green color channel to attain the median.
                 Channel[1] /= Bitmap.Width;
                 // Divide the blue color channel to attain the median.
                 Channel[2] /= Bitmap.Width;
                 // Check if the line is considered to be white.
                 if (Channel[0] >= 245 && Channel[1] >= 245 && Channel[2] >= 245) {
                     // Set the incision line.
                     Incision = PreviousBlack + FirstBlack;
                 }
             }
         }
         // Check if an incision line is available.
         if (Incision != -1) {
             // Initialize the rectangle.
             Rectangle Rectangle = new Rectangle(0, 0, Bitmap.Width, Bitmap.Height - Incision);
             // Initialize the result.
             Bitmap Result = Bitmap.Clone(Rectangle, Bitmap.PixelFormat);
             // Dispose of the image.
             Bitmap.Dispose();
             // Return the result.
             return Result;
         }
     }
     // Return the bitmap.
     return Bitmap;
 }
 /// <summary>
 /// Sharpen using a gaussian sharpen filter.
 /// </summary>
 public static Bitmap Sharpen(this Bitmap Bitmap)
 {
     // Convert grayscale to RGB colour space.
     if ((Bitmap = Bitmap.Channel()) != null) {
         // Initialize a new instance of the GaussianSharpen class.
         var GaussianSharpen = new GaussianSharpen();
         // Apply the filter to the image.
         GaussianSharpen.ApplyInPlace(Bitmap);
     }
     // Return the bitmap.
     return Bitmap;
 }
 /// <summary>
 /// Reduce noise using conservative smoothing.
 /// </summary>
 public static Bitmap Noise(this Bitmap Bitmap)
 {
     // Convert grayscale to RGB colour space.
     if ((Bitmap = Bitmap.Channel()) != null) {
         // Initialize a new instance of the ConservativeSmoothing class.
         var ConservativeSmoothing = new ConservativeSmoothing();
         // Reduce noise while preserving detail.
         ConservativeSmoothing.ApplyInPlace(Bitmap);
     }
     // Return the bitmap.
     return Bitmap;
 }
 /// <summary>
 /// Convert RGB colour space to grayscale when applicable.
 /// </summary>
 public static Bitmap Grayscale(this Bitmap Bitmap)
 {
     // Convert grayscale to RGB colour space.
     if ((Bitmap = Bitmap.Channel()) != null) {
         // Initialize a new instance of the ImageStatisticsHSL class.
         ImageStatisticsHSL ImageStatisticsHSL = new ImageStatisticsHSL(Bitmap);
         // Check if the image is grayscale.
         if (ImageStatisticsHSL.Saturation.Max == 0) {
             // Initialize a new instance of the Grayscale class.
             Grayscale Grayscale = new Grayscale(0.2125, 0.7154, 0.0721);
             // Apply the filter to the image.
             Bitmap Result = Grayscale.Apply(Bitmap);
             // Dispose of the original image.
             Bitmap.Dispose();
             // Return the result.
             return Result;
         }
     }
     // Return the bitmap.
     return Bitmap;
 }
 /// <summary>
 /// Returns the channel time series represented by the series of entries
 /// </summary>
 public static IEnumerable<IEnumerable<double>> Channels(this IEnumerable<EEGDataEntry> entries)
 {
     return MCAEmotiv.Interop.Channels.Values.Select(ch => entries.Channel(ch));
 }