Conservative smoothing.

The filter implements conservative smoothing, which is a noise reduction technique that derives its name from the fact that it employs a simple, fast filtering algorithm that sacrifices noise suppression power in order to preserve the high spatial frequency detail (e.g. sharp edges) in an image. It is explicitly designed to remove noise spikes - isolated pixels of exceptionally low or high pixel intensity (salt and pepper noise).

If the filter finds a pixel which has minimum/maximum value compared to its surrounding pixel, then its value is replaced by minimum/maximum value of those surrounding pixel. For example, lets suppose the filter uses kernel size of 3x3, which means each pixel has 8 surrounding pixel. If pixel's value is smaller than any value of surrounding pixels, then the value of the pixel is replaced by minimum value of those surrounding pixels.

The filter accepts 8 bpp grayscale images and 24/32 bpp color images for processing.

Sample usage:

// create filter ConservativeSmoothing filter = new ConservativeSmoothing( ); // apply the filter filter.ApplyInPlace( image );

Initial image:

Result image:

Inheritance: BaseUsingCopyPartialFilter
		/// <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;
		}
 private void button27_Click(object sender, EventArgs e)
 {
     IFilter imgeFilter = new ConservativeSmoothing();
     img = imgeFilter.Apply(img);
     panelImage.BackgroundImage = img;
     panelMenu.Visible = false;
 }
示例#3
0
        private void button17_Click(object sender, EventArgs e)
        {
            if (KeyFileName != null)
            {
                GUIStart("Extracting Watermark...");

                List<int> PNSeq = new List<int>();

                StreamReader objstream = new StreamReader(KeyFileName);
                string[] lines = objstream.ReadToEnd().Split(new char[] { '\n' });
                int height = Convert.ToInt32(lines[4]);
                int width = Convert.ToInt32(lines[5]);
                int NumOfTrees = Convert.ToInt32(lines[7]);
                for (int i = 9; i < lines.Length - 1; i++)
                {
                    PNSeq.Add(Convert.ToInt32(lines[i]));
                }

                #region Extracting Image
                ///Not using 15 bit mapping
                Bitmap bmp = ImageProcessing.ConvertListToWatermark2(ExtractedWatermark, height, width);
                //watermarkImage.Image = bmp;
                //Bitmap bmp = new Bitmap(watermarkImage.Image);               
                ConservativeSmoothing filter = new ConservativeSmoothing();
                filter.ApplyInPlace(bmp);
                //extractedImageRed.Image = bmp;
                #endregion

                /// Test
                int counter = 0;
                for (int i = 0; i < ExtractedWatermark.Length; i++)
                {
                    if(ExtractedWatermark[i] == Real_Watermark[i])
                    {
                        counter++;
                    }
                }
                double akurasi = ((double)counter/(double)ExtractedWatermark.Length)*100;
                double BER = 100 - akurasi;
                bertxt.Text += Math.Round(BER,2)+"\n";
                //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);

                GUIEnd("Watermark Extracted!", 0, 0, 0);
            }
            else
            {
                MessageBox.Show("Train and Detect Watermark first!", "Incomplete Procedure Detected", MessageBoxButtons.OK);
            }                
        }
 public static Bitmap ApplyImageSmoothing(Bitmap pBitmap)
 {
     var filter = new ConservativeSmoothing();
     return filter.Apply(pBitmap);
 }
示例#5
0
        private void button18_Click(object sender, EventArgs e) /// Extract Watermark At Once
        {
            if(dwtTypeValue2.Text == "Haar")
            {
                GUIStart("Extracting Watermark...");

                #region Training HMM and Detection
                /// Detection            
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Title = "Select a key accordingly";
                ofd.InitialDirectory = @"F:\College\Semester 8\TA2\TugasAkhir1\TugasAkhir1\Key";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    StreamReader objstream = new StreamReader(ofd.FileName);
                    string[] lines = objstream.ReadToEnd().Split(new char[] { '\n' });
                    int hostheight = Convert.ToInt32(lines[1]);
                    int hostwidth = Convert.ToInt32(lines[2]);
                    int NumOfTrees = Convert.ToInt32(lines[7]);
                    KeyFileName = ofd.FileName;

                    /// Get PNSeq
                    List<int> PNSeq = new List<int>();
                    for (int i = 9; i < lines.Length - 1; i++)
                    {
                        PNSeq.Add(Convert.ToInt32(lines[i]));
                    }

                    //GUIStart("Training HMM Model...");
                    //transformedImage.Image = DWT.TransformDWT(true, false, 2, OriginalImage);

                    ///For Wavelet Coefficients Extraction
                    Bitmap b = new Bitmap(transformedImage.Image);
                    IMatrixR = ImageProcessing.ConvertToMatrix2(b).Item1;
                    IMatrixG = ImageProcessing.ConvertToMatrix2(b).Item2;
                    IMatrixB = ImageProcessing.ConvertToMatrix2(b).Item3;

                    double[,] ArrayImage = IMatrixG; //Embedding in Green 
                                                     //Watermarked_Wavelet_Coefficients = Haar.WaveletCoeff(ArrayImage, true, 2);
                    RedWatermarked_Wavelet_Coefficients = Haar.WaveletCoeff(IMatrixR, true, 2);
                    GreenWatermarked_Wavelet_Coefficients = Haar.WaveletCoeff(IMatrixG, true, 2);
                    BlueWatermarked_Wavelet_Coefficients = Haar.WaveletCoeff(IMatrixB, true, 2);

                    int NumOfScale2 = ((hostheight * hostwidth) / 16) * 3;


                    Image decomposed = Haar.TransformDWT(true, false, 2, new Bitmap(transformedImage.Image)).Item4;
                    //RedExtractedWatermark = Extract.BaumWelchDetectionRGB(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq , "red"/*, rootpmf, transition, variances*/);
                    //GreenExtractedWatermark = Extract.BaumWelchDetectionRGB(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green" /*, rootpmf, transition, variances*/);
                    //BlueExtractedWatermark = Extract.BaumWelchDetectionRGB(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "blue" /*, rootpmf, transition, variances*/);
                    string subband = subbandValue2.Text;
                    double embed_constant = Convert.ToDouble(embedConstantValue2.Text);
                    if (HVSValue.Text == "Xie Model")
                    {
                        RedExtractedWatermark = Extract.BaumWelchDetectionInLH_2(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Red", subband, embed_constant);
                        GreenExtractedWatermark = Extract.BaumWelchDetectionInLH_2(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green", subband, embed_constant);
                        BlueExtractedWatermark = Extract.BaumWelchDetectionInLH_2(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Blue", subband, embed_constant);
                    }
                    else
                    {
                        RedExtractedWatermark = Extract.BaumWelchDetectionInLH_22(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Red", subband, embed_constant);
                        GreenExtractedWatermark = Extract.BaumWelchDetectionInLH_22(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green", subband, embed_constant);
                        BlueExtractedWatermark = Extract.BaumWelchDetectionInLH_22(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Blue", subband, embed_constant);
                    }

                }
                else
                {
                    MessageBox.Show("Select Key accordingly first!", "Incomplete Procedure Detected", MessageBoxButtons.OK);
                }
                #endregion

                #region Extraction
                if (KeyFileName != null)
                {
                    GUIStart("Extracting Watermark...");

                    List<int> PNSeq = new List<int>();

                    StreamReader objstream = new StreamReader(KeyFileName);
                    string[] lines = objstream.ReadToEnd().Split(new char[] { '\n' });
                    int height = Convert.ToInt32(lines[4]);
                    int width = Convert.ToInt32(lines[5]);
                    int NumOfTrees = Convert.ToInt32(lines[7]);
                    for (int i = 9; i < lines.Length - 1; i++)
                    {
                        PNSeq.Add(Convert.ToInt32(lines[i]));
                    }

                    #region Extracting Image in Red
                    /////Not using 15 bit mapping
                    //Bitmap redbmp = ImageProcessing.ConvertListToWatermark2(RedExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter = new ConservativeSmoothing();
                    //filter.ApplyInPlace(redbmp);
                    //extractedImageRed.Image = redbmp;
                    #endregion

                    #region Extraction Image in Green
                    /////Not using 15 bit mapping
                    //Bitmap greenbmp = ImageProcessing.ConvertListToWatermark2(GreenExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter2 = new ConservativeSmoothing();
                    //filter2.ApplyInPlace(greenbmp);
                    //extractedImageGreen.Image = greenbmp;
                    #endregion

                    #region Extraction Image in Blue
                    /////Not using 15 bit mapping
                    //Bitmap bluebmp = ImageProcessing.ConvertListToWatermark2(BlueExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter3 = new ConservativeSmoothing();
                    //filter3.ApplyInPlace(greenbmp);
                    //extractedImageBlue.Image = bluebmp;
                    #endregion

                    #region Get Final Result
                    double[] finalresult = Extract.FinalResult(RedExtractedWatermark, GreenExtractedWatermark, BlueExtractedWatermark);
                    Bitmap finalbmp = ImageProcessing.ConvertListToWatermark2(finalresult, height, width);
                    ConservativeSmoothing filter4 = new ConservativeSmoothing();
                    filter4.ApplyInPlace(finalbmp);
                    FinalResult.Image = finalbmp;
                    #endregion

                    FResult = finalresult;

                    if (watermarkImage.Image != null && Real_Watermark!=null)
                    {
                        #region Red BER Calculation
                        /// Test
                        int counter = 0;
                        for (int i = 0; i < RedExtractedWatermark.Length; i++)
                        {
                            if (RedExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter++;
                            }
                        }
                        double akurasi = ((double)counter / (double)RedExtractedWatermark.Length) * 100;
                        double BER = 100 - akurasi;
                        //bertxt.Text += "> " + Math.Round(BER, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //RedextractedBERtxt.Text = Math.Round(BER, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion

                        #region Green BER Calculation
                        /// Test
                        int counter2 = 0;
                        for (int i = 0; i < GreenExtractedWatermark.Length; i++)
                        {
                            if (GreenExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter2++;
                            }
                        }
                        double akurasi2 = ((double)counter2 / (double)GreenExtractedWatermark.Length) * 100;
                        double BER2 = 100 - akurasi2;
                        //bertxt.Text += "> " + Math.Round(BER2, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //GreenextractedBERtxt.Text = Math.Round(BER2, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion

                        #region Blue BER Calculation
                        /// Test
                        int counter3 = 0;
                        for (int i = 0; i < BlueExtractedWatermark.Length; i++)
                        {
                            if (BlueExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter3++;
                            }
                        }
                        double akurasi3 = ((double)counter3 / (double)BlueExtractedWatermark.Length) * 100;
                        double BER3 = 100 - akurasi3;
                        //bertxt.Text += "> " + Math.Round(BER3, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //BlueextractedBERtxt.Text = Math.Round(BER3, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion

                        #region Final BER Calculation
                        /// Test
                        int counter4 = 0;
                        for (int i = 0; i < finalresult.Length; i++)
                        {
                            if (finalresult[i] == Real_Watermark[i])
                            {
                                counter4++;
                            }
                        }
                        double akurasi4 = ((double)counter4 / (double)finalresult.Length) * 100;
                        double BER4 = 100 - akurasi4;
                        bertxt.Text += "> " + Math.Round(BER4, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        finalBerValue.Text = Math.Round(BER4, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion
                    }

                    GUIEnd("Watermark Extracted!", 0, 0, 0);
                }
                else
                {
                    MessageBox.Show("Train and Detect Watermark first!", "Incomplete Procedure Detected", MessageBoxButtons.OK);
                }
                #endregion

                GUIEnd("Watermark Extracted!", 0, 0, 0);
            }
            else if(dwtTypeValue2.Text == "Db2")
            {
                GUIStart("Extracting Watermark...");

                #region Training HMM and Detection
                /// Detection            
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Title = "Select a key accordingly";
                ofd.InitialDirectory = @"F:\College\Semester 8\TA2\TugasAkhir1\TugasAkhir1\Key";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    StreamReader objstream = new StreamReader(ofd.FileName);
                    string[] lines = objstream.ReadToEnd().Split(new char[] { '\n' });
                    int hostheight = Convert.ToInt32(lines[1]);
                    int hostwidth = Convert.ToInt32(lines[2]);
                    int NumOfTrees = Convert.ToInt32(lines[7]);
                    KeyFileName = ofd.FileName;

                    /// Get PNSeq
                    List<int> PNSeq = new List<int>();
                    for (int i = 9; i < lines.Length - 1; i++)
                    {
                        PNSeq.Add(Convert.ToInt32(lines[i]));
                    }

                    GUIStart("Training HMM Model...");
                    //transformedImage.Image = DWT.TransformDWT(true, false, 2, OriginalImage);

                    ///For Wavelet Coefficients Extraction
                    Bitmap b = new Bitmap(transformedImage.Image);
                    IMatrixR = ImageProcessing.ConvertToMatrix2(b).Item1;
                    IMatrixG = ImageProcessing.ConvertToMatrix2(b).Item2;
                    IMatrixB = ImageProcessing.ConvertToMatrix2(b).Item3;

                    double[,] ArrayImage = IMatrixG; //Embedding in Green 
                                                     //Watermarked_Wavelet_Coefficients = Haar.WaveletCoeff(ArrayImage, true, 2);
                    RedWatermarked_Wavelet_Coefficients = Daubechies2.WaveletCoeff(IMatrixR, true, 2);
                    GreenWatermarked_Wavelet_Coefficients = Daubechies2.WaveletCoeff(IMatrixG, true, 2);
                    BlueWatermarked_Wavelet_Coefficients = Daubechies2.WaveletCoeff(IMatrixB, true, 2);

                    int NumOfScale2 = ((hostheight * hostwidth) / 16) * 3;


                    Image decomposed = Haar.TransformDWT(true, false, 2, new Bitmap(transformedImage.Image)).Item4;
                    //RedExtractedWatermark = Extract.BaumWelchDetectionRGB(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq , "red"/*, rootpmf, transition, variances*/);
                    //GreenExtractedWatermark = Extract.BaumWelchDetectionRGB(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green" /*, rootpmf, transition, variances*/);
                    //BlueExtractedWatermark = Extract.BaumWelchDetectionRGB(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "blue" /*, rootpmf, transition, variances*/);
                    string subband = subbandValue2.Text;
                    double embed_constant = Convert.ToDouble(embedConstantValue2.Text);
                    if (HVSValue.Text == "Xie Model")
                    {
                        RedExtractedWatermark = Extract.BaumWelchDetectionInLH_2(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Red", subband, embed_constant);
                        GreenExtractedWatermark = Extract.BaumWelchDetectionInLH_2(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green", subband, embed_constant);
                        BlueExtractedWatermark = Extract.BaumWelchDetectionInLH_2(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Blue", subband, embed_constant);
                    }
                    else
                    {
                        RedExtractedWatermark = Extract.BaumWelchDetectionInLH_22(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Red", subband, embed_constant);
                        GreenExtractedWatermark = Extract.BaumWelchDetectionInLH_22(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green", subband, embed_constant);
                        BlueExtractedWatermark = Extract.BaumWelchDetectionInLH_22(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Blue", subband, embed_constant);
                    }

                }
                else
                {
                    MessageBox.Show("Select Key accordingly first!", "Incomplete Procedure Detected", MessageBoxButtons.OK);
                }
                #endregion

                #region Extraction
                if (KeyFileName != null)
                {
                    GUIStart("Extracting Watermark...");

                    List<int> PNSeq = new List<int>();

                    StreamReader objstream = new StreamReader(KeyFileName);
                    string[] lines = objstream.ReadToEnd().Split(new char[] { '\n' });
                    int height = Convert.ToInt32(lines[4]);
                    int width = Convert.ToInt32(lines[5]);
                    int NumOfTrees = Convert.ToInt32(lines[7]);
                    for (int i = 9; i < lines.Length - 1; i++)
                    {
                        PNSeq.Add(Convert.ToInt32(lines[i]));
                    }

                    #region Extracting Image in Red
                    /////Not using 15 bit mapping
                    //Bitmap redbmp = ImageProcessing.ConvertListToWatermark2(RedExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter = new ConservativeSmoothing();
                    //filter.ApplyInPlace(redbmp);
                    //extractedImageRed.Image = redbmp;
                    #endregion

                    #region Extraction Image in Green
                    /////Not using 15 bit mapping
                    //Bitmap greenbmp = ImageProcessing.ConvertListToWatermark2(GreenExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter2 = new ConservativeSmoothing();
                    //filter2.ApplyInPlace(greenbmp);
                    //extractedImageGreen.Image = greenbmp;
                    #endregion

                    #region Extraction Image in Blue
                    /////Not using 15 bit mapping
                    //Bitmap bluebmp = ImageProcessing.ConvertListToWatermark2(BlueExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter3 = new ConservativeSmoothing();
                    //filter3.ApplyInPlace(greenbmp);
                    //extractedImageBlue.Image = bluebmp;
                    #endregion

                    #region Get Final Result
                    double[] finalresult = Extract.FinalResult(RedExtractedWatermark, GreenExtractedWatermark, BlueExtractedWatermark);
                    Bitmap finalbmp = ImageProcessing.ConvertListToWatermark2(finalresult, height, width);
                    ConservativeSmoothing filter4 = new ConservativeSmoothing();
                    filter4.ApplyInPlace(finalbmp);
                    FinalResult.Image = finalbmp;
                    #endregion

                    FResult = finalresult;

                    if (watermarkImage.Image != null && Real_Watermark != null)
                    {
                        #region Red BER Calculation
                        /// Test
                        int counter = 0;
                        for (int i = 0; i < RedExtractedWatermark.Length; i++)
                        {
                            if (RedExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter++;
                            }
                        }
                        double akurasi = ((double)counter / (double)RedExtractedWatermark.Length) * 100;
                        double BER = 100 - akurasi;
                        //bertxt.Text += "> " + Math.Round(BER, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //RedextractedBERtxt.Text = Math.Round(BER, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion

                        #region Green BER Calculation
                        /// Test
                        int counter2 = 0;
                        for (int i = 0; i < GreenExtractedWatermark.Length; i++)
                        {
                            if (GreenExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter2++;
                            }
                        }
                        double akurasi2 = ((double)counter2 / (double)GreenExtractedWatermark.Length) * 100;
                        double BER2 = 100 - akurasi2;
                        //bertxt.Text += "> " + Math.Round(BER2, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //GreenextractedBERtxt.Text = Math.Round(BER2, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion

                        #region Blue BER Calculation
                        /// Test
                        int counter3 = 0;
                        for (int i = 0; i < BlueExtractedWatermark.Length; i++)
                        {
                            if (BlueExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter3++;
                            }
                        }
                        double akurasi3 = ((double)counter3 / (double)BlueExtractedWatermark.Length) * 100;
                        double BER3 = 100 - akurasi3;
                        //bertxt.Text += "> " + Math.Round(BER3, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //BlueextractedBERtxt.Text = Math.Round(BER3, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion

                        #region Final BER Calculation
                        /// Test
                        int counter4 = 0;
                        for (int i = 0; i < finalresult.Length; i++)
                        {
                            if (finalresult[i] == Real_Watermark[i])
                            {
                                counter4++;
                            }
                        }
                        double akurasi4 = ((double)counter4 / (double)finalresult.Length) * 100;
                        double BER4 = 100 - akurasi4;
                        bertxt.Text += "> " + Math.Round(BER4, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        finalBerValue.Text = Math.Round(BER4, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion
                    }

                    GUIEnd("Watermark Extracted!", 0, 0, 0);
                }
                else
                {
                    MessageBox.Show("Train and Detect Watermark first!", "Incomplete Procedure Detected", MessageBoxButtons.OK);
                }
                #endregion

                GUIEnd("Watermark Extracted!", 0, 0, 0);
            }
            else
            {
                GUIStart("Extracting Watermark...");

                #region Training HMM and Detection
                /// Detection            
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Title = "Select a key accordingly";
                ofd.InitialDirectory = @"F:\College\Semester 8\TA2\TugasAkhir1\TugasAkhir1\Key";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    StreamReader objstream = new StreamReader(ofd.FileName);
                    string[] lines = objstream.ReadToEnd().Split(new char[] { '\n' });
                    int hostheight = Convert.ToInt32(lines[1]);
                    int hostwidth = Convert.ToInt32(lines[2]);
                    int NumOfTrees = Convert.ToInt32(lines[7]);
                    KeyFileName = ofd.FileName;

                    /// Get PNSeq
                    List<int> PNSeq = new List<int>();
                    for (int i = 9; i < lines.Length - 1; i++)
                    {
                        PNSeq.Add(Convert.ToInt32(lines[i]));
                    }

                    GUIStart("Training HMM Model...");
                    //transformedImage.Image = DWT.TransformDWT(true, false, 2, OriginalImage);

                    ///For Wavelet Coefficients Extraction
                    Bitmap b = new Bitmap(transformedImage.Image);
                    IMatrixR = ImageProcessing.ConvertToMatrix2(b).Item1;
                    IMatrixG = ImageProcessing.ConvertToMatrix2(b).Item2;
                    IMatrixB = ImageProcessing.ConvertToMatrix2(b).Item3;

                    double[,] ArrayImage = IMatrixG; //Embedding in Green 
                                                     //Watermarked_Wavelet_Coefficients = Haar.WaveletCoeff(ArrayImage, true, 2);
                    RedWatermarked_Wavelet_Coefficients = Daubechies3.WaveletCoeff(IMatrixR, true, 2);
                    GreenWatermarked_Wavelet_Coefficients = Daubechies3.WaveletCoeff(IMatrixG, true, 2);
                    BlueWatermarked_Wavelet_Coefficients = Daubechies3.WaveletCoeff(IMatrixB, true, 2);

                    int NumOfScale2 = ((hostheight * hostwidth) / 16) * 3;


                    Image decomposed = Haar.TransformDWT(true, false, 2, new Bitmap(transformedImage.Image)).Item4;
                    //RedExtractedWatermark = Extract.BaumWelchDetectionRGB(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq , "red"/*, rootpmf, transition, variances*/);
                    //GreenExtractedWatermark = Extract.BaumWelchDetectionRGB(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green" /*, rootpmf, transition, variances*/);
                    //BlueExtractedWatermark = Extract.BaumWelchDetectionRGB(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "blue" /*, rootpmf, transition, variances*/);
                    string subband = subbandValue2.Text;
                    double embed_constant = Convert.ToDouble(embedConstantValue2.Text);
                    if (HVSValue.Text == "Xie Model")
                    {
                        RedExtractedWatermark = Extract.BaumWelchDetectionInLH_2(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Red", subband, embed_constant);
                        GreenExtractedWatermark = Extract.BaumWelchDetectionInLH_2(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green", subband, embed_constant);
                        BlueExtractedWatermark = Extract.BaumWelchDetectionInLH_2(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Blue", subband, embed_constant);
                    }
                    else
                    {
                        RedExtractedWatermark = Extract.BaumWelchDetectionInLH_22(RedWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Red", subband, embed_constant);
                        GreenExtractedWatermark = Extract.BaumWelchDetectionInLH_22(GreenWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "green", subband, embed_constant);
                        BlueExtractedWatermark = Extract.BaumWelchDetectionInLH_22(BlueWatermarked_Wavelet_Coefficients, decomposed, NumOfScale2, NumOfTrees, PNSeq, "Blue", subband, embed_constant);
                    }

                }
                else
                {
                    MessageBox.Show("Select Key accordingly first!", "Incomplete Procedure Detected", MessageBoxButtons.OK);
                }
                #endregion

                #region Extraction
                if (KeyFileName != null)
                {
                    GUIStart("Extracting Watermark...");

                    List<int> PNSeq = new List<int>();

                    StreamReader objstream = new StreamReader(KeyFileName);
                    string[] lines = objstream.ReadToEnd().Split(new char[] { '\n' });
                    int height = Convert.ToInt32(lines[4]);
                    int width = Convert.ToInt32(lines[5]);
                    int NumOfTrees = Convert.ToInt32(lines[7]);
                    for (int i = 9; i < lines.Length - 1; i++)
                    {
                        PNSeq.Add(Convert.ToInt32(lines[i]));
                    }

                    #region Extracting Image in Red
                    /////Not using 15 bit mapping
                    //Bitmap redbmp = ImageProcessing.ConvertListToWatermark2(RedExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter = new ConservativeSmoothing();
                    //filter.ApplyInPlace(redbmp);
                    //extractedImageRed.Image = redbmp;
                    #endregion

                    #region Extraction Image in Green
                    /////Not using 15 bit mapping
                    //Bitmap greenbmp = ImageProcessing.ConvertListToWatermark2(GreenExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter2 = new ConservativeSmoothing();
                    //filter2.ApplyInPlace(greenbmp);
                    //extractedImageGreen.Image = greenbmp;
                    #endregion

                    #region Extraction Image in Blue
                    /////Not using 15 bit mapping
                    //Bitmap bluebmp = ImageProcessing.ConvertListToWatermark2(BlueExtractedWatermark, height, width);
                    ////watermarkImage.Image = bmp;
                    ////Bitmap bmp = new Bitmap(watermarkImage.Image);               
                    //ConservativeSmoothing filter3 = new ConservativeSmoothing();
                    //filter3.ApplyInPlace(greenbmp);
                    //extractedImageBlue.Image = bluebmp;
                    #endregion

                    #region Get Final Result
                    double[] finalresult = Extract.FinalResult(RedExtractedWatermark, GreenExtractedWatermark, BlueExtractedWatermark);
                    Bitmap finalbmp = ImageProcessing.ConvertListToWatermark2(finalresult, height, width);
                    ConservativeSmoothing filter4 = new ConservativeSmoothing();
                    filter4.ApplyInPlace(finalbmp);
                    FinalResult.Image = finalbmp;
                    #endregion

                    FResult = finalresult;

                    if (watermarkImage.Image != null && Real_Watermark != null)
                    {
                        #region Red BER Calculation
                        /// Test
                        int counter = 0;
                        for (int i = 0; i < RedExtractedWatermark.Length; i++)
                        {
                            if (RedExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter++;
                            }
                        }
                        double akurasi = ((double)counter / (double)RedExtractedWatermark.Length) * 100;
                        double BER = 100 - akurasi;
                        //bertxt.Text += "> " + Math.Round(BER, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //RedextractedBERtxt.Text = Math.Round(BER, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion

                        #region Green BER Calculation
                        /// Test
                        int counter2 = 0;
                        for (int i = 0; i < GreenExtractedWatermark.Length; i++)
                        {
                            if (GreenExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter2++;
                            }
                        }
                        double akurasi2 = ((double)counter2 / (double)GreenExtractedWatermark.Length) * 100;
                        double BER2 = 100 - akurasi2;
                        //bertxt.Text += "> " + Math.Round(BER2, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //GreenextractedBERtxt.Text = Math.Round(BER2, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion

                        #region Blue BER Calculation
                        /// Test
                        int counter3 = 0;
                        for (int i = 0; i < BlueExtractedWatermark.Length; i++)
                        {
                            if (BlueExtractedWatermark[i] == Real_Watermark[i])
                            {
                                counter3++;
                            }
                        }
                        double akurasi3 = ((double)counter3 / (double)BlueExtractedWatermark.Length) * 100;
                        double BER3 = 100 - akurasi3;
                        //bertxt.Text += "> " + Math.Round(BER3, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        //BlueextractedBERtxt.Text = Math.Round(BER3, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion


                        #region Final BER Calculation
                        /// Test
                        int counter4 = 0;
                        for (int i = 0; i < finalresult.Length; i++)
                        {
                            if (finalresult[i] == Real_Watermark[i])
                            {
                                counter4++;
                            }
                        }
                        double akurasi4 = ((double)counter4 / (double)finalresult.Length) * 100;
                        double BER4 = 100 - akurasi4;
                        bertxt.Text += "> " + Math.Round(BER4, 2) + " %" + "\n";
                        //double BER = Statistic.BER(new Bitmap(watermarkImage.Image), new Bitmap(extractedImageGreen.Image));
                        finalBerValue.Text = Math.Round(BER4, 2).ToString();
                        //MessageBox.Show("Akurasi: " + BER, "Succeed!", MessageBoxButtons.OK);
                        #endregion
                    }

                    GUIEnd("Watermark Extracted!", 0, 0, 0);
                }
                else
                {
                    MessageBox.Show("Train and Detect Watermark first!", "Incomplete Procedure Detected", MessageBoxButtons.OK);
                }
                #endregion

                GUIEnd("Watermark Extracted!", 0, 0, 0);
            }
            
        }
示例#6
0
文件: Form1.cs 项目: Slavedogg/PennX
        private void FillPictureBoxes(ref Bitmap image)
        {
            Bitmap tmpImg  = image;
            Bitmap tmpImg2 = image;


            try
            {
                bool hasFilter = false;
                //setup resize and filtersequesce


                //resize img to fit picturebox
                ResizeBicubic resizeFilter = new ResizeBicubic(0, 0);

                resizeFilter = new ResizeBicubic(pbCapture.Width, pbCapture.Height);
                tmpImg       = resizeFilter.Apply(tmpImg);

                resizeFilter = new ResizeBicubic(pbShapes.Width, pbShapes.Height);
                tmpImg2      = resizeFilter.Apply(tmpImg2);



                FiltersSequence processingFilter = new FiltersSequence();


                //List all filters
                IFilter ConservativeSmoothingFilter = new AForge.Imaging.Filters.ConservativeSmoothing();
                IFilter InvertFilter          = new AForge.Imaging.Filters.Invert();
                IFilter HSLFilteringFilter    = new AForge.Imaging.Filters.HSLFiltering();
                IFilter SepiaFilter           = new AForge.Imaging.Filters.Sepia();
                IFilter grayscaleFilter       = new AForge.Imaging.Filters.GrayscaleBT709();
                IFilter SkeletonizationFilter = new AForge.Imaging.Filters.SimpleSkeletonization();
                IFilter pixFilter             = new AForge.Imaging.Filters.Pixellate();


                ////apply filter and process img---------------------------------------------



                if (ConservativeSmoothing)
                {
                    processingFilter.Add(ConservativeSmoothingFilter);
                    hasFilter = true;
                }

                if (Invert)
                {
                    processingFilter.Add(InvertFilter);
                    hasFilter = true;
                }

                if (HSLswitch)
                {
                    processingFilter.Add(HSLFilteringFilter);
                    hasFilter = true;
                }

                if (sepiaSwitch)
                {
                    processingFilter.Add(SepiaFilter);
                    hasFilter = true;
                }


                if (Skeletonization)
                {
                    processingFilter.Add(grayscaleFilter);
                    processingFilter.Add(SkeletonizationFilter);
                    hasFilter = true;
                }

                //apply the filter(s) to image
                if (hasFilter)
                {
                    //tmpImg = processingFilter.Apply(tmpImg);
                    tmpImg2 = processingFilter.Apply(tmpImg2);
                }

                processingFilter.Clear();


                if (bwSwitch)
                {
                    switchBandW(ref tmpImg);
                }



                if (CannyEdgeDetector)
                {
                    // create filter
                    CannyEdgeDetector filter = new CannyEdgeDetector();
                    // apply the filter
                    tmpImg = Grayscale.CommonAlgorithms.BT709.Apply(tmpImg);
                    filter.ApplyInPlace(tmpImg);


                    // image = DrawFocusArea(gsImage);
                }
                else
                {
                    // image = DrawFocusArea(image);
                }


                if (DifferenceEdgeDetector)
                {
                    DifferenceEdgeDetector dFilter = new DifferenceEdgeDetector();
                    // apply the filter
                    tmpImg = Grayscale.CommonAlgorithms.BT709.Apply(tmpImg);
                    dFilter.ApplyInPlace(tmpImg);
                }


                if (HomogenityEdgeDetector)
                {
                    HomogenityEdgeDetector hFilter = new HomogenityEdgeDetector();
                    // apply the filter
                    tmpImg = Grayscale.CommonAlgorithms.BT709.Apply(tmpImg);
                    hFilter.ApplyInPlace(tmpImg);
                }


                if (SobelEdgeDetector)
                {
                    SobelEdgeDetector hFilter = new SobelEdgeDetector();
                    // apply the filter
                    tmpImg = Grayscale.CommonAlgorithms.BT709.Apply(tmpImg);
                    hFilter.ApplyInPlace(tmpImg);

                    BlobCounter bc    = new BlobCounter(tmpImg);
                    Rectangle[] brecs = bc.GetObjectsRectangles();


                    //Graphics pg = Graphics.FromImage(tmpImg);
                    //Pen p = new Pen(Color.White, 2);

                    //foreach (Rectangle r in brecs)
                    //{
                    //    pg.DrawRectangle(p, r);
                    //}
                }



                if (findShapes)
                {
                    tmpImg = FindShapes(tmpImg, ref tmpImg2);
                    //ProcessImage(image);
                }
                else
                {
                    pbCapture.Image = tmpImg;  //set picturebox image----------------
                    pbShapes.Image  = tmpImg2; //set picturebox image----------------
                }



                // Graphics g = Graphics.FromImage(tmpImg);
                // Pen p = new Pen(Color.Red, 2);

                // Rectangle lr = new Rectangle(100, 120, 80, 40);
                //// Rectangle rr = new Rectangle(360, 220, 80, 40);

                // g.DrawRectangle(p, lr);
                // //g.DrawRectangle(p, rr);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


            //  pbCapture.Image = tmpImg;//set picturebox image----------------
            //   pbShapes.Image = tmpImg2;//set picturebox image----------------
        }
 /// <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;
 }
        public Bitmap Detect(Bitmap bitmap)
        {
            Bitmap grayscaleBitmap = Grayscale.CommonAlgorithms.BT709.Apply(bitmap);

            IFilter smoothingFilter = null;
            switch (_smoothMode)
            {
                case "None": smoothingFilter = null; break;
                case "Mean": smoothingFilter = new Mean(); break;
                case "Median": smoothingFilter = new Median(); break;
                case "Conservative": smoothingFilter = new ConservativeSmoothing(); break;
                case "Adaptive": smoothingFilter = new AdaptiveSmoothing(); break;
                case "Bilateral": smoothingFilter = new BilateralSmoothing(); break;
            }
            Bitmap smoothBitmap = smoothingFilter != null ? smoothingFilter.Apply(grayscaleBitmap) : grayscaleBitmap;

            IFilter edgeFilter = null;
            switch (_edgeMode)
            {
                case "Homogenity": edgeFilter = new HomogenityEdgeDetector(); break;
                case "Difference": edgeFilter = new DifferenceEdgeDetector(); break;
                case "Sobel": edgeFilter = new SobelEdgeDetector(); break;
                case "Canny": edgeFilter = new CannyEdgeDetector(); break;
            }
            Bitmap edgeBitmap = edgeFilter != null ? edgeFilter.Apply(smoothBitmap) : smoothBitmap;

            IFilter threshholdFilter = new Threshold(_threshold);
            Bitmap thresholdBitmap = _threshold == 0 ? edgeBitmap : threshholdFilter.Apply(edgeBitmap);

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = _minHeight;
            blobCounter.MinWidth = _minWidth;
            blobCounter.ProcessImage(thresholdBitmap);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            Bitmap outputBitmap = new Bitmap(thresholdBitmap.Width, thresholdBitmap.Height, PixelFormat.Format24bppRgb);
            Graphics bitmapGraphics = Graphics.FromImage(outputBitmap);
            Bitmap inputBitmap = null;
            switch (_drawMode)
            {
                case "Original": inputBitmap = bitmap; break;
                case "Grayscale": inputBitmap = grayscaleBitmap; break;
                case "Smooth": inputBitmap = smoothBitmap; break;
                case "Edge": inputBitmap = edgeBitmap; break;
                case "Threshold": inputBitmap = thresholdBitmap; break;
            }
            if (inputBitmap != null)
                bitmapGraphics.DrawImage(inputBitmap, 0, 0);

            Pen nonConvexPen = new Pen(Color.Red, 2);
            Pen nonRectPen = new Pen(Color.Orange, 2);
            Pen cardPen = new Pen(Color.Blue, 2);

            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            List<IntPoint> cardPositions = new List<IntPoint>();

            for (int i = 0; i < blobs.Length; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> corners;

                if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                {
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);

                    if ((subType == PolygonSubType.Parallelogram || subType == PolygonSubType.Rectangle) && corners.Count == 4)
                    {
                        // Check if its sideways, if so rearrange the corners so it's vertical.
                        RearrangeCorners(corners);

                        // Prevent detecting the same card twice by comparing distance against other detected cards.
                        bool sameCard = false;
                        foreach (IntPoint point in cardPositions)
                        {
                            if (corners[0].DistanceTo(point) < _minDistance)
                            {
                                sameCard = true;
                                break;
                            }
                        }
                        if (sameCard)
                            continue;

                        // Hack to prevent it from detecting smaller sections of the card instead of the whole card.
                        if (GetArea(corners) < _minArea)
                            continue;

                        cardPositions.Add(corners[0]);

                        bitmapGraphics.DrawPolygon(cardPen, ToPointsArray(corners));
                    }
                    else
                    {
                        foreach (IntPoint point in edgePoints.Take(300))
                        {
                            bitmapGraphics.DrawEllipse(nonRectPen, point.X, point.Y, 1, 1);
                        }
                    }
                }
                else
                {
                    foreach (IntPoint point in edgePoints.Take(300))
                    {
                        bitmapGraphics.DrawEllipse(nonConvexPen, point.X, point.Y, 1, 1);
                    }
                }
            }

            bitmapGraphics.Dispose();
            nonConvexPen.Dispose();
            nonRectPen.Dispose();
            cardPen.Dispose();

            return outputBitmap;
        }
示例#9
0
        /// <summary>
        /// <para>Pulls the image</para>
        /// <para>Runs the ocr on it</para>
        /// <para>fills in the blanks</para>
        /// <para>submits the page</para>
        /// </summary>
        /// <param name="challenge"></param>
        /// <param name="cancellationToken"></param>
        /// <param name="answer"></param>
        /// <returns></returns>
        private bool SolveCaptcha( Uri challenge, CancellationToken cancellationToken, out String answer ) {
            answer = null;
            var tesseractEngine = this.TesseractEngine;
            if ( null == tesseractEngine ) {
                return false;
            }

            var captchaData = this.PullCaptchaData( challenge );

            if ( captchaData.ImageUri == null ) {
                captchaData.Status = CaptchaStatus.NoImageFoundToBeSolved;
                this.UpdateCaptchaData( captchaData );
                return false;
            }

            Console.WriteLine( Resources.Uber_SolveCaptcha_Attempting_OCR_on__0_, captchaData.ImageUri.AbsolutePath );

            captchaData.Status = CaptchaStatus.SolvingImage;
            this.UpdateCaptchaData( captchaData );

            var folder = new Folder( Path.GetTempPath() );

            Document document;
            folder.TryGetTempDocument( document: out document, extension: "png" );

            this.PictureBoxChallenge.Image.Save( document.FullPathWithFileName, ImageFormat.Png );

            var aforgeImage = AForge.Imaging.Image.FromFile( document.FullPathWithFileName );

            var smoothing = new ConservativeSmoothing();

            var cannyEdgeDetector = new CannyEdgeDetector();

            cannyEdgeDetector.Apply( aforgeImage );

            aforgeImage.Save( document.FullPathWithFileName, ImageFormat.Png );

            this.PictureBoxChallenge.ImageLocation = document.FullPathWithFileName;

            this.PictureBoxChallenge.Load();

            this.Throttle( Seconds.Ten );

            using ( var img = Pix.LoadFromFile( document.FullPathWithFileName ).Deskew() ) {

                using ( var page = tesseractEngine.Process( img, PageSegMode.SingleLine ) ) {

                    answer = page.GetText();

                    var paragraph = new Paragraph( answer );

                    answer = new Sentence( paragraph.ToStrings( " " ) ).ToStrings( " " );

                    FluentTimers.Create( Minutes.One, () => document.Delete() ).AndStart();

                    if ( !String.IsNullOrWhiteSpace( answer ) ) {
                        captchaData.Status = CaptchaStatus.SolvedChallenge;
                        this.UpdateCaptchaData( captchaData );
                        return true;
                    }

                    return false;
                }
            }
        }