Пример #1
0
        public void ShlTest()
        {
            const int            RepeatCount = 5;
            UlongRandomGenerator random      = new UlongRandomGenerator();

            ulong[] y    = new ulong[3];
            ulong[] copy = new ulong[3];
            int     size = y.Length * 64;

            for (int count = 0; count <= size; count++)
            {
                for (int pos = 0; pos < size - count; pos++)
                {
                    for (int shift = 0; shift <= count; shift++)
                    {
                        for (int i = 0; i < RepeatCount; i++)
                        {
                            random.Generate(y.Length, y);
                            Vectors.Copy(y.Length, y, 0, copy, 0);
                            BitUtils.Shl(count, shift, y, pos);

                            // right part that was not copied
                            if (pos > 0)
                            {
                                Assert.IsTrue(BitUtils.Equals(pos, y, 0, copy, 0));
                            }

                            // shifted part
                            if (shift < count)
                            {
                                Assert.IsTrue(BitUtils.Equals(count - shift, y, pos + shift, copy, pos));
                            }

                            // zeroed part
                            if (shift > 0)
                            {
                                Assert.AreEqual(0, BitUtils.CountOneBits(shift, y, pos));
                            }

                            // left part that was not copied
                            if (pos + count < size)
                            {
                                Assert.IsTrue(BitUtils.Equals(size - (pos + count), y, pos + count, copy, pos + count));
                            }
                        }
                    }
                }
            }
        }
Пример #2
0
        public void SetBitsTest()
        {
            const int Size = 3 * 64;

            ulong[] y = new ulong[3];

            for (int count = 1; count < Size; count++)
            {
                for (int pos = 0; pos < Size - count; pos++)
                {
                    y[0] = y[1] = y[2] = 0;
                    BitUtils.SetBits(count, y, pos);

                    Assert.AreEqual(count, BitUtils.CountOneBits(Size, y, 0));

                    Assert.AreEqual(pos, BitUtils.BitScanOneForward(Size, y, 0));
                    Assert.AreEqual(pos + count - 1, BitUtils.BitScanOneReverse(Size, y, Size - 1));

                    Assert.AreEqual(pos + count == Size ? -1 : pos + count, BitUtils.BitScanZeroForward(Size - pos, y, pos));
                    Assert.AreEqual(pos == 0 ? -1 : pos - 1, BitUtils.BitScanZeroReverse(pos + count, y, pos + count - 1));
                }
            }
        }
Пример #3
0
        /// <summary>
        /// De-skews the <see cref="Image"/> and aligns it horizontally.
        /// </summary>
        /// <param name="dst">The destination <see cref="Image"/>. Can be <b>null</b>.</param>
        /// <returns>
        /// The destination <see cref="Image"/>.
        /// </returns>
        /// <exception cref="NotImplementedException">
        /// <see cref="Image{T}.BitsPerPixel"/> is not one.
        /// </exception>
        /// <remarks>
        /// <para>This method works with binary (1bpp) images only.</para>
        /// </remarks>
        public Image Deskew(Image dst)
        {
            if (this.BitsPerPixel != 1)
            {
                throw new NotImplementedException(Properties.Resources.E_UnsupportedDepth_1bpp);
            }

            int width  = this.Width;
            int height = this.Height;
            int stride = this.Stride;

            ulong[] bits = this.Bits;

            // build histogram
            ulong endMask = this.EndMask;

            float[][] histogram = new float[stride][];
            for (int ix = 0; ix < stride; ix++)
            {
                float[] h    = histogram[ix] = new float[height];
                ulong   mask = ix == stride - 1 ? endMask : ulong.MaxValue;
                for (int iy = 0, off = ix; iy < height; iy++, off += stride)
                {
                    h[iy] = BitUtils.CountOneBits(bits[off] & mask);
                }
            }

            // calculate image variance
            float angleBest    = 0.0f;
            float varianceBest = EstimateSkewAngle(angleBest);

            // move up or down with 1 degree interval
            // move counterclockwise
            for (float angle = -1.0f; angle >= -10.0f; angle -= 1.0f)
            {
                float variance = EstimateSkewAngle(angle);
                if (variance <= varianceBest)
                {
                    break;
                }

                varianceBest = variance;
                angleBest    = angle;
            }

            if (angleBest == 0.0f)
            {
                // move clockwise
                for (float angle = 1.0f; angle <= 10.0f; angle += 1.0f)
                {
                    float variance = EstimateSkewAngle(angle);
                    if (variance <= varianceBest)
                    {
                        break;
                    }

                    varianceBest = variance;
                    angleBest    = angle;
                }
            }

            // move up or down with 0.1 degree interval
            // move counterclockwise
            float originalAngle = angleBest;

            for (float angle = angleBest - 0.1f, max = angleBest - 0.9f; angle >= max; angle -= 0.1f)
            {
                float variance = EstimateSkewAngle(angle);
                if (variance <= varianceBest)
                {
                    break;
                }

                varianceBest = variance;
                angleBest    = angle;
            }

            if (originalAngle == angleBest)
            {
                // move clockwise
                for (float angle = angleBest + 0.1f, max = angleBest + 0.9f; angle <= max; angle += 0.1f)
                {
                    float variance = EstimateSkewAngle(angle);
                    if (variance <= varianceBest)
                    {
                        break;
                    }

                    varianceBest = variance;
                    angleBest    = angle;
                }
            }

            return(this.Rotate(dst, -angleBest, BorderType.BorderRepl, 0));

            float EstimateSkewAngle(float angle)
            {
                const float PiConv = 3.1415926535f / 180.0f;

                int   centerX = width / 2;
                float dblTanA = (float)Math.Tan(angle * PiConv);

                float[] ds = new float[height];

                for (int ix = 0; ix < stride; ix++)
                {
                    // negative shift is down
                    int shiftY = (dblTanA * (centerX - (ix * 64) - 32)).Round();

                    Mathematics.Add(
                        height - Math.Abs(shiftY),
                        histogram[ix],
                        shiftY < 0 ? 0 : shiftY,
                        ds,
                        shiftY < 0 ? -shiftY : 0);
                }

                return(ds.Variance());
            }
        }