Пример #1
0
 public static int binarize_simple(Bytearray result, Bytearray image)
 {
     int threshold = (NarrayUtil.Max(image)/* + NarrayUtil.Min(image)*/) / 2;
     result.MakeLike(image);
     for (int i = 0; i < image.Length1d(); i++)
         result.Put1d(i, image.At1d(i) < threshold ? (byte)0 : (byte)255);
     return threshold;
 }
Пример #2
0
 public static void binarize_with_threshold(Bytearray result, Floatarray image, float threshold)
 {
     result.MakeLike(image);
     for (int i = 0; i < image.Length1d(); i++)
     {
         result.Put1d(i, image.At1d(i) < threshold ? (byte)0 : (byte)255);
     }
 }
Пример #3
0
        public static int binarize_simple(Bytearray result, Bytearray image)
        {
            int threshold = (NarrayUtil.Max(image) /* + NarrayUtil.Min(image)*/) / 2;

            result.MakeLike(image);
            for (int i = 0; i < image.Length1d(); i++)
            {
                result.Put1d(i, image.At1d(i) < threshold ? (byte)0 : (byte)255);
            }
            return(threshold);
        }
Пример #4
0
 public static void binarize_by_range(Bytearray outa, Floatarray ina, float fraction)
 {
     float imin = NarrayUtil.Min(ina);
     float imax = NarrayUtil.Max(ina);
     float thresh = (int)(imin + (imax - imin) * fraction);
     outa.MakeLike(ina);
     for (int i = 0; i < ina.Length1d(); i++)
     {
         if (ina.At1d(i) > thresh) outa.Put1d(i, 255);
         else outa.Put1d(i, 0);
     }
 }
Пример #5
0
 public static void segmentation_as_bitmap(Bytearray image, Intarray cseg)
 {
     image.MakeLike(cseg);
     for (int i = 0; i < image.Length1d(); i++)
     {
         int value = cseg.At1d(i);
         if (value == 0 || value == 0xffffff)
         {
             image.Put1d(i, 255);
         }
         //if (value == 0xffffff) image.Put1d(i, 255);
     }
 }
Пример #6
0
        public static void binarize_by_range(Bytearray outa, Floatarray ina, float fraction)
        {
            float imin   = NarrayUtil.Min(ina);
            float imax   = NarrayUtil.Max(ina);
            float thresh = (int)(imin + (imax - imin) * fraction);

            outa.MakeLike(ina);
            for (int i = 0; i < ina.Length1d(); i++)
            {
                if (ina.At1d(i) > thresh)
                {
                    outa.Put1d(i, 255);
                }
                else
                {
                    outa.Put1d(i, 0);
                }
            }
        }
Пример #7
0
        public static void extract_holes(ref Bytearray holes, Bytearray binarized)
        {
            Intarray temp = new Intarray();

            temp.Copy(binarized);
            NarrayUtil.Sub(255, temp);
            ImgLabels.label_components(ref temp);
            int background = -1;

            for (int i = 0; i < temp.Dim(0); i++)
            {
                if (temp[i, 0] != 0)
                {
                    background = temp[i, 0];
                    break;
                }
            }
            holes.MakeLike(temp);
            holes.Fill((byte)0);
            if (background <= 0)
            {
                throw new Exception("extract_holes: background must be more 0");
            }
            for (int i = 0; i < temp.Dim(0); i++)
            {
                for (int j = 0; j < temp.Dim(1); j++)
                {
                    if (temp[i, j] > 0 && temp[i, j] != background)
                    {
                        holes[i, j] = 255;
                    }
                }
            }

            /*fprintf(stderr, "segholes\n");
             * dsection("segholes");
             * dshow(holes, "y");*/
        }
Пример #8
0
        public override void Binarize(Bytearray bin_image, Bytearray gray_image)
        {
            w     = PGeti("w");
            k     = (float)PGetf("k");
            whalf = w >> 1;
            // fprintf(stderr,"[sauvola %g %d]\n",k,w);
            if (k < 0.001 || k > 0.999)
            {
                throw new Exception("Binarize: CHECK_ARG(k>=0.001 && k<=0.999)");
            }
            if (w == 0 || k >= 1000)
            {
                throw new Exception("Binarize: CHECK_ARG(w>0 && k<1000)");
            }
            if (bin_image.Length1d() != gray_image.Length1d())
            {
                bin_image.MakeLike(gray_image);
            }

            if (NarrayUtil.contains_only(gray_image, (byte)0, (byte)255))
            {
                bin_image.Copy(gray_image);
                return;
            }

            int image_width  = gray_image.Dim(0);
            int image_height = gray_image.Dim(1);

            whalf = w >> 1;

            // Calculate the integral image, and integral of the squared image
            Narray <long> integral_image = new Narray <long>(), rowsum_image = new Narray <long>();
            Narray <long> integral_sqimg = new Narray <long>(), rowsum_sqimg = new Narray <long>();

            integral_image.MakeLike(gray_image);
            rowsum_image.MakeLike(gray_image);
            integral_sqimg.MakeLike(gray_image);
            rowsum_sqimg.MakeLike(gray_image);
            int    xmin, ymin, xmax, ymax;
            double diagsum, idiagsum, diff, sqdiagsum, sqidiagsum, sqdiff, area;
            double mean, std, threshold;

            for (int j = 0; j < image_height; j++)
            {
                rowsum_image[0, j] = gray_image[0, j];
                rowsum_sqimg[0, j] = gray_image[0, j] * gray_image[0, j];
            }
            for (int i = 1; i < image_width; i++)
            {
                for (int j = 0; j < image_height; j++)
                {
                    rowsum_image[i, j] = rowsum_image[i - 1, j] + gray_image[i, j];
                    rowsum_sqimg[i, j] = rowsum_sqimg[i - 1, j] + gray_image[i, j] * gray_image[i, j];
                }
            }

            for (int i = 0; i < image_width; i++)
            {
                integral_image[i, 0] = rowsum_image[i, 0];
                integral_sqimg[i, 0] = rowsum_sqimg[i, 0];
            }
            for (int i = 0; i < image_width; i++)
            {
                for (int j = 1; j < image_height; j++)
                {
                    integral_image[i, j] = integral_image[i, j - 1] + rowsum_image[i, j];
                    integral_sqimg[i, j] = integral_sqimg[i, j - 1] + rowsum_sqimg[i, j];
                }
            }

            //Calculate the mean and standard deviation using the integral image

            for (int i = 0; i < image_width; i++)
            {
                for (int j = 0; j < image_height; j++)
                {
                    xmin = Math.Max(0, i - whalf);
                    ymin = Math.Max(0, j - whalf);
                    xmax = Math.Min(image_width - 1, i + whalf);
                    ymax = Math.Min(image_height - 1, j + whalf);
                    area = (xmax - xmin + 1) * (ymax - ymin + 1);
                    // area can't be 0 here
                    // proof (assuming whalf >= 0):
                    // we'll prove that (xmax-xmin+1) > 0,
                    // (ymax-ymin+1) is analogous
                    // It's the same as to prove: xmax >= xmin
                    // image_width - 1 >= 0         since image_width > i >= 0
                    // i + whalf >= 0               since i >= 0, whalf >= 0
                    // i + whalf >= i - whalf       since whalf >= 0
                    // image_width - 1 >= i - whalf since image_width > i
                    // --IM
                    if (area <= 0)
                    {
                        throw new Exception("Binarize: area can't be 0 here");
                    }
                    if (xmin == 0 && ymin == 0)
                    { // Point at origin
                        diff   = integral_image[xmax, ymax];
                        sqdiff = integral_sqimg[xmax, ymax];
                    }
                    else if (xmin == 0 && ymin > 0)
                    { // first column
                        diff   = integral_image[xmax, ymax] - integral_image[xmax, ymin - 1];
                        sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmax, ymin - 1];
                    }
                    else if (xmin > 0 && ymin == 0)
                    { // first row
                        diff   = integral_image[xmax, ymax] - integral_image[xmin - 1, ymax];
                        sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmin - 1, ymax];
                    }
                    else
                    { // rest of the image
                        diagsum    = integral_image[xmax, ymax] + integral_image[xmin - 1, ymin - 1];
                        idiagsum   = integral_image[xmax, ymin - 1] + integral_image[xmin - 1, ymax];
                        diff       = diagsum - idiagsum;
                        sqdiagsum  = integral_sqimg[xmax, ymax] + integral_sqimg[xmin - 1, ymin - 1];
                        sqidiagsum = integral_sqimg[xmax, ymin - 1] + integral_sqimg[xmin - 1, ymax];
                        sqdiff     = sqdiagsum - sqidiagsum;
                    }

                    mean      = diff / area;
                    std       = Math.Sqrt((sqdiff - diff * diff / area) / (area - 1));
                    threshold = mean * (1 + k * ((std / 128) - 1));
                    if (gray_image[i, j] < threshold)
                    {
                        bin_image[i, j] = 0;
                    }
                    else
                    {
                        bin_image[i, j] = (byte)(MAXVAL - 1);
                    }
                }
            }
            if (PGeti("debug_binarize") > 0)
            {
                ImgIo.write_image_gray("debug_binarize.png", bin_image);
            }
        }
Пример #9
0
        public override void Binarize(Bytearray bin_image, Bytearray gray_image)
        {
            w = PGeti("w");
            k = (float)PGetf("k");
            whalf = w >> 1;
            // fprintf(stderr,"[sauvola %g %d]\n",k,w);
            if(k<0.001 || k>0.999)
                throw new Exception("Binarize: CHECK_ARG(k>=0.001 && k<=0.999)");
            if(w==0 || k>=1000)
                throw new Exception("Binarize: CHECK_ARG(w>0 && k<1000)");
            if(bin_image.Length1d() != gray_image.Length1d())
                bin_image.MakeLike(gray_image);

            if(NarrayUtil.contains_only(gray_image, (byte)0, (byte)255))
            {
                bin_image.Copy(gray_image);
                return;
            }

            int image_width  = gray_image.Dim(0);
            int image_height = gray_image.Dim(1);
            whalf = w >> 1;

            // Calculate the integral image, and integral of the squared image
            Narray<long> integral_image = new Narray<long>(), rowsum_image = new Narray<long>();
            Narray<long> integral_sqimg = new Narray<long>(), rowsum_sqimg = new Narray<long>();
            integral_image.MakeLike(gray_image);
            rowsum_image.MakeLike(gray_image);
            integral_sqimg.MakeLike(gray_image);
            rowsum_sqimg.MakeLike(gray_image);
            int xmin,ymin,xmax,ymax;
            double diagsum,idiagsum,diff,sqdiagsum,sqidiagsum,sqdiff,area;
            double mean,std,threshold;

            for (int j = 0; j < image_height; j++)
            {
                rowsum_image[0, j] = gray_image[0, j];
                rowsum_sqimg[0, j] = gray_image[0, j] * gray_image[0, j];
            }
            for (int i = 1; i < image_width; i++)
            {
                for (int j = 0; j < image_height; j++)
                {
                    rowsum_image[i, j] = rowsum_image[i - 1, j] + gray_image[i, j];
                    rowsum_sqimg[i, j] = rowsum_sqimg[i - 1, j] + gray_image[i, j] * gray_image[i, j];
                }
            }

            for (int i = 0; i < image_width; i++)
            {
                integral_image[i, 0] = rowsum_image[i, 0];
                integral_sqimg[i, 0] = rowsum_sqimg[i, 0];
            }
            for (int i = 0; i < image_width; i++)
            {
                for (int j = 1; j < image_height; j++)
                {
                    integral_image[i, j] = integral_image[i, j - 1] + rowsum_image[i, j];
                    integral_sqimg[i, j] = integral_sqimg[i, j - 1] + rowsum_sqimg[i, j];
                }
            }

            //Calculate the mean and standard deviation using the integral image

            for(int i=0; i<image_width; i++){
                for(int j=0; j<image_height; j++){
                    xmin = Math.Max(0,i-whalf);
                    ymin = Math.Max(0, j - whalf);
                    xmax = Math.Min(image_width - 1, i + whalf);
                    ymax = Math.Min(image_height - 1, j + whalf);
                    area = (xmax-xmin+1)*(ymax-ymin+1);
                    // area can't be 0 here
                    // proof (assuming whalf >= 0):
                    // we'll prove that (xmax-xmin+1) > 0,
                    // (ymax-ymin+1) is analogous
                    // It's the same as to prove: xmax >= xmin
                    // image_width - 1 >= 0         since image_width > i >= 0
                    // i + whalf >= 0               since i >= 0, whalf >= 0
                    // i + whalf >= i - whalf       since whalf >= 0
                    // image_width - 1 >= i - whalf since image_width > i
                    // --IM
                    if (area <= 0)
                        throw new Exception("Binarize: area can't be 0 here");
                    if (xmin == 0 && ymin == 0)
                    { // Point at origin
                        diff = integral_image[xmax, ymax];
                        sqdiff = integral_sqimg[xmax, ymax];
                    }
                    else if (xmin == 0 && ymin > 0)
                    { // first column
                        diff = integral_image[xmax, ymax] - integral_image[xmax, ymin - 1];
                        sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmax, ymin - 1];
                    }
                    else if (xmin > 0 && ymin == 0)
                    { // first row
                        diff = integral_image[xmax, ymax] - integral_image[xmin - 1, ymax];
                        sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmin - 1, ymax];
                    }
                    else
                    { // rest of the image
                        diagsum = integral_image[xmax, ymax] + integral_image[xmin - 1, ymin - 1];
                        idiagsum = integral_image[xmax, ymin - 1] + integral_image[xmin - 1, ymax];
                        diff = diagsum - idiagsum;
                        sqdiagsum = integral_sqimg[xmax, ymax] + integral_sqimg[xmin - 1, ymin - 1];
                        sqidiagsum = integral_sqimg[xmax, ymin - 1] + integral_sqimg[xmin - 1, ymax];
                        sqdiff = sqdiagsum - sqidiagsum;
                    }

                    mean = diff/area;
                    std  = Math.Sqrt((sqdiff - diff*diff/area)/(area-1));
                    threshold = mean*(1+k*((std/128)-1));
                    if(gray_image[i,j] < threshold)
                        bin_image[i,j] = 0;
                    else
                        bin_image[i,j] = (byte)(MAXVAL-1);
                }
            }
            if(PGeti("debug_binarize") > 0) {
                ImgIo.write_image_gray("debug_binarize.png", bin_image);
            }
        }
Пример #10
0
        public override void Binarize(Bytearray bin_image, Bytearray gray_image)
        {
            if(bin_image.Length1d() != gray_image.Length1d())
                bin_image.MakeLike(gray_image);

            if(NarrayUtil.contains_only(gray_image, (byte)0, (byte)255))
            {
                bin_image.Copy(gray_image);
                return;
            }

            int image_width  = gray_image.Dim(0);
            int image_height = gray_image.Dim(1);
            int[]    hist = new int[MAXVAL];
            double[] pdf = new double[MAXVAL]; //probability distribution
            double[] cdf = new double[MAXVAL]; //cumulative probability distribution
            double[] myu = new double[MAXVAL];   // mean value for separation
            double max_sigma;
            double[] sigma = new double[MAXVAL]; // inter-class variance

            /* Histogram generation */
            for(int i=0; i<MAXVAL; i++){
                hist[i] = 0;
            }
            for(int x=0; x<image_width; x++){
                for(int y=0; y<image_height; y++){
                    hist[gray_image[x,y]]++;
                }
            }

            /* calculation of probability density */
            for(int i=0; i<MAXVAL; i++){
                pdf[i] = (double)hist[i] / (image_width * image_height);
            }

            /* cdf & myu generation */
            cdf[0] = pdf[0];
            myu[0] = 0.0;       /* 0.0 times prob[0] equals zero */
            for(int i=1; i<MAXVAL; i++){
                cdf[i] = cdf[i-1] + pdf[i];
                myu[i] = myu[i-1] + i*pdf[i];
            }

            /* sigma maximization
               sigma stands for inter-class variance
               and determines optimal threshold value */
            int threshold = 0;
            max_sigma = 0.0;
            for(int i=0; i<MAXVAL-1; i++){
                if(cdf[i] != 0.0 && cdf[i] != 1.0){
                    double p1p2 = cdf[i]*(1.0 - cdf[i]);
                    double mu1mu2diff = myu[MAXVAL-1]*cdf[i]-myu[i];
                    sigma[i] = mu1mu2diff * mu1mu2diff / p1p2;
                }
                else
                    sigma[i] = 0.0;
                if(sigma[i] > max_sigma){
                    max_sigma = sigma[i];
                    threshold = i;
                }
            }

            for(int x=0; x<image_width; x++){
                for(int y=0; y<image_height; y++){
                     if (gray_image[x,y] > threshold)
                        bin_image[x,y] = (byte)(MAXVAL-1);
                    else
                        bin_image[x,y] = 0;
                }
            }

            if(PGeti("debug_otsu") > 0) {
                Logger.Default.Format("Otsu threshold value = {0}\n", threshold);
                //ImgIo.write_image_gray("debug_otsu.png", bin_image);
            }
        }
Пример #11
0
 public static void binarize_with_threshold(Bytearray result, Floatarray image, float threshold)
 {
     result.MakeLike(image);
     for (int i = 0; i < image.Length1d(); i++)
         result.Put1d(i, image.At1d(i) < threshold ? (byte)0 : (byte)255);
 }
Пример #12
0
        public override void Binarize(Bytearray bin_image, Bytearray gray_image)
        {
            if (bin_image.Length1d() != gray_image.Length1d())
            {
                bin_image.MakeLike(gray_image);
            }

            if (NarrayUtil.contains_only(gray_image, (byte)0, (byte)255))
            {
                bin_image.Copy(gray_image);
                return;
            }

            int image_width  = gray_image.Dim(0);
            int image_height = gray_image.Dim(1);

            int[]    hist = new int[MAXVAL];
            double[] pdf  = new double[MAXVAL]; //probability distribution
            double[] cdf  = new double[MAXVAL]; //cumulative probability distribution
            double[] myu  = new double[MAXVAL]; // mean value for separation
            double   max_sigma;

            double[] sigma = new double[MAXVAL]; // inter-class variance

            /* Histogram generation */
            for (int i = 0; i < MAXVAL; i++)
            {
                hist[i] = 0;
            }
            for (int x = 0; x < image_width; x++)
            {
                for (int y = 0; y < image_height; y++)
                {
                    hist[gray_image[x, y]]++;
                }
            }

            /* calculation of probability density */
            for (int i = 0; i < MAXVAL; i++)
            {
                pdf[i] = (double)hist[i] / (image_width * image_height);
            }

            /* cdf & myu generation */
            cdf[0] = pdf[0];
            myu[0] = 0.0;       /* 0.0 times prob[0] equals zero */
            for (int i = 1; i < MAXVAL; i++)
            {
                cdf[i] = cdf[i - 1] + pdf[i];
                myu[i] = myu[i - 1] + i * pdf[i];
            }

            /* sigma maximization
             * sigma stands for inter-class variance
             * and determines optimal threshold value */
            int threshold = 0;

            max_sigma = 0.0;
            for (int i = 0; i < MAXVAL - 1; i++)
            {
                if (cdf[i] != 0.0 && cdf[i] != 1.0)
                {
                    double p1p2       = cdf[i] * (1.0 - cdf[i]);
                    double mu1mu2diff = myu[MAXVAL - 1] * cdf[i] - myu[i];
                    sigma[i] = mu1mu2diff * mu1mu2diff / p1p2;
                }
                else
                {
                    sigma[i] = 0.0;
                }
                if (sigma[i] > max_sigma)
                {
                    max_sigma = sigma[i];
                    threshold = i;
                }
            }


            for (int x = 0; x < image_width; x++)
            {
                for (int y = 0; y < image_height; y++)
                {
                    if (gray_image[x, y] > threshold)
                    {
                        bin_image[x, y] = (byte)(MAXVAL - 1);
                    }
                    else
                    {
                        bin_image[x, y] = 0;
                    }
                }
            }

            if (PGeti("debug_otsu") > 0)
            {
                Logger.Default.Format("Otsu threshold value = {0}\n", threshold);
                //ImgIo.write_image_gray("debug_otsu.png", bin_image);
            }
        }