/// <summary> /// The update thresholds. /// </summary> private void UpdateThresholds() { YCbCrColor targetColorInYCbCr = YCbCrColor.FromArgbColor(this.targetColor); this.LowerThreshold = new YCbCrColor( 0.1f, targetColorInYCbCr.Cb - this.threshold / 500f, targetColorInYCbCr.Cr - this.threshold / 500f); this.UpperThreshold = new YCbCrColor( 1.0f, targetColorInYCbCr.Cb + this.threshold / 500f, targetColorInYCbCr.Cr + this.threshold / 500f); }
/// <summary> /// Initializes a new instance of the <see cref="ColorAndCropFilterYCbCr" /> class. /// </summary> public ColorAndCropFilterYCbCr() { this.LowerThreshold = YCbCrColor.Min; this.UpperThreshold = YCbCrColor.Max; this.pixelColor = new YCbCrColor(0, 0, 0); }
/// <summary> /// Process the filter on the specified image. /// </summary> /// <param name="image"> /// Source image data. /// </param> public override unsafe void ProcessInPlace(IntPtr image) { int t = this.Threshold; int ipx = this.ImagePixelSize; Color target = this.TargetColor; Color blank = this.BlankColor; int rMin = target.R - t; int rMax = target.R + t; int gMin = target.G - t; int gMax = target.G + t; int bMin = target.B - t; int bMax = target.B + t; Rect cropRect = this.CropRectangle; double xMin = cropRect.Left; double xMax = cropRect.Right; double yMin = cropRect.Top; double yMax = cropRect.Bottom; YCbCrColor lowThres = this.LowerThreshold; YCbCrColor hightThres = this.UpperThreshold; float lowThresY = lowThres.Y; float lowThresCb = lowThres.Cb; float lowThresCr = lowThres.Cr; float highThresY = hightThres.Y; float highThresCb = hightThres.Cb; float highThresCr = hightThres.Cr; // int startX = 0; // int startY = 0; // int stopX = startX + this.ImageWidth; // int stopY = startY + this.ImageHeight; int offset = this.ImageStride - this.ImageWidth * this.ImagePixelSize; // do the job var ptr = (byte *)image; // Threshold every pixel for (int i = 0; i < this.ImageWidth * this.ImageHeight; i++, ptr += ipx) { this.UpdatePixelColorFromRgb(ptr[R], ptr[G], ptr[B]); if (this.pixelColor.Y >= lowThresY && this.pixelColor.Y <= highThresY && this.pixelColor.Cb >= lowThresCb && this.pixelColor.Cb <= highThresCb && this.pixelColor.Cr >= lowThresCr && this.pixelColor.Cr <= highThresCr) { continue; } else { ptr[R] = blank.R; ptr[G] = blank.G; ptr[B] = blank.B; } // ptr += offset; } // byte r, g, b; //// allign pointer to the first pixel to process // ptr += (startY * this.ImageStride + startX * ipx); //// for each row // for (int y = startY; y < stopY; y++) // { // // Blank cropped area // if (y < yMin || y > yMax) // { // // Blank whole line // for (int x = startX; x < stopX; x++, ptr += ipx) // { // ptr[R] = blank.R; // ptr[G] = blank.G; // ptr[B] = blank.B; // } // // go to next line // ptr += offset; // continue; // } // // for each pixel // for (int x = startX; x < stopX; x++, ptr += ipx) // { // // blank cropped pixels // if (x < xMin || x > xMax) // { // ptr[R] = blank.R; // ptr[G] = blank.G; // ptr[B] = blank.B; // } // else // { // ycbcr = YCbCrColor.FromRgb(ptr[R], ptr[G], ptr[B]); // if (ycbcr.Y >= lowThresY && ycbcr.Y <= highThresY // && ycbcr.Cb >= lowThresCb && ycbcr.Cb <= highThresCb // && ycbcr.Cr >= lowThresCr && ycbcr.Cr <= highThresCr) // { // continue; // } // else // { // ptr[R] = blank.R; // ptr[G] = blank.G; // ptr[B] = blank.B; // } // } // } // ptr += offset; // } }
/// <summary> /// The interpolate. /// </summary> /// <param name="c2"> /// The c 2. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <returns> /// The <see cref="YCbCrColor"/> . /// </returns> public YCbCrColor Interpolate(YCbCrColor c2, float amount) { return(new YCbCrColor( this.Y + (c2.Y - this.Y) * amount, this.Cb + (c2.Cb - this.Cb) * amount, this.Cr + (c2.Cr - this.Cr) * amount)); }