Exemplo n.º 1
0
        private void blurToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                var bitmap = pictureEdit1.Image as Bitmap;
                if (bitmap == null)
                {
                    throw new Exception("Нет изображения");
                }

                var size          = bitmap.Size;
                var blinderDialog = new BlinderDialog(new Size(size.Width / 2, size.Height / 2));

                if (blinderDialog.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                var filterSize = blinderDialog.BlinderSize;


                using (var builder = new BlurBuilder(filterSize))
                {
                    pictureEdit1.Image = builder.Blur(bitmap);
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
Exemplo n.º 2
0
        private void blur_ItemClick(object sender, ItemClickEventArgs e)
        {
            try
            {
                var bitmap = pictureEdit1.Image as Bitmap;
                if (bitmap == null)
                {
                    return;
                }
                var size = bitmap.Size;
                using (var blinderDialog = new BlinderDialog(new Size(size.Width * 3 / 4, size.Height * 3 / 4)))
                {
                    if (blinderDialog.ShowDialog() != DialogResult.OK)
                    {
                        return;
                    }

                    var blinderSize = blinderDialog.BlinderSize;

                    using (var builder = new BlurBuilder(blinderSize))
                        pictureEdit1.Image = builder.Blur(bitmap);
                }
            }
            catch (Exception exception)
            {
                XtraMessageBox.Show(exception.Message);
            }
        }
Exemplo n.º 3
0
        public void BlurTestMethod()
        {
            const int width      = 100;
            const int height     = 100;
            const int filterStep = 1;

            var image = new Image <Gray, byte>(height, width);
            var bytes = new byte[image.Data.Length];

            Rng.GetBytes(bytes);

            var handle = GCHandle.Alloc(image.Data, GCHandleType.Pinned);

            Marshal.Copy(bytes, 0, handle.AddrOfPinnedObject(), bytes.Length);
            handle.Free();

            var average  = bytes.Average(x => (double)x);
            var delta    = Math.Sqrt(bytes.Average(x => (double)x * x) - average * average);
            var minValue = bytes.Min(x => (double)x);
            var maxValue = bytes.Max(x => (double)x);
            var sb       = new StringBuilder();

            sb.AppendLine(string.Format("Length {0}", bytes.Length));
            sb.AppendLine(string.Format("Average {0}", average));
            sb.AppendLine(string.Format("Delta {0}", delta));
            sb.AppendLine(string.Format("minValue {0}", minValue));
            sb.AppendLine(string.Format("maxValue {0}", maxValue));
            Console.WriteLine(sb.ToString());

            using (var blurBuilder = new BlurBuilder(filterStep))
                image = blurBuilder.Blur(image);

            handle = GCHandle.Alloc(image.Data, GCHandleType.Pinned);
            Marshal.Copy(handle.AddrOfPinnedObject(), bytes, 0, bytes.Length);
            handle.Free();

            var average1  = bytes.Average(x => (double)x);
            var delta1    = Math.Sqrt(bytes.Average(x => (double)x * x) - average1 * average1);
            var minValue1 = bytes.Min(x => (double)x);
            var maxValue1 = bytes.Max(x => (double)x);
            var sb1       = new StringBuilder();

            sb1.AppendLine(string.Format("Length {0}", bytes.Length));
            sb1.AppendLine(string.Format("Average {0}", average1));
            sb1.AppendLine(string.Format("Delta {0}", delta1));
            sb1.AppendLine(string.Format("minValue {0}", minValue1));
            sb1.AppendLine(string.Format("maxValue {0}", maxValue1));
            Console.WriteLine(sb1.ToString());

            Assert.IsTrue(delta1 < delta);
        }
Exemplo n.º 4
0
        public void BlurTestMethod()
        {
            const int width = 100;
            const int height = 100;
            const int filterStep = 1;

            var image = new Image<Gray, byte>(height, width);
            var bytes = new byte[image.Data.Length];

            Rng.GetBytes(bytes);

            var handle = GCHandle.Alloc(image.Data, GCHandleType.Pinned);
            Marshal.Copy(bytes, 0, handle.AddrOfPinnedObject(), bytes.Length);
            handle.Free();

            var average = bytes.Average(x => (double) x);
            var delta = Math.Sqrt(bytes.Average(x => (double) x*x) - average*average);
            var minValue = bytes.Min(x => (double) x);
            var maxValue = bytes.Max(x => (double) x);
            var sb = new StringBuilder();
            sb.AppendLine(string.Format("Length {0}", bytes.Length));
            sb.AppendLine(string.Format("Average {0}", average));
            sb.AppendLine(string.Format("Delta {0}", delta));
            sb.AppendLine(string.Format("minValue {0}", minValue));
            sb.AppendLine(string.Format("maxValue {0}", maxValue));
            Console.WriteLine(sb.ToString());

            using (var blurBuilder = new BlurBuilder(filterStep))
                image = blurBuilder.Blur(image);

            handle = GCHandle.Alloc(image.Data, GCHandleType.Pinned);
            Marshal.Copy(handle.AddrOfPinnedObject(), bytes, 0, bytes.Length);
            handle.Free();

            var average1 = bytes.Average(x => (double) x);
            var delta1 = Math.Sqrt(bytes.Average(x => (double) x*x) - average1*average1);
            var minValue1 = bytes.Min(x => (double) x);
            var maxValue1 = bytes.Max(x => (double) x);
            var sb1 = new StringBuilder();
            sb1.AppendLine(string.Format("Length {0}", bytes.Length));
            sb1.AppendLine(string.Format("Average {0}", average1));
            sb1.AppendLine(string.Format("Delta {0}", delta1));
            sb1.AppendLine(string.Format("minValue {0}", minValue1));
            sb1.AppendLine(string.Format("maxValue {0}", maxValue1));
            Console.WriteLine(sb1.ToString());

            Assert.IsTrue(delta1 < delta);
        }
Exemplo n.º 5
0
        public void BlurTestMethod()
        {
            const int width      = 100;
            const int height     = 100;
            const int filterStep = 1;

            var image = new Image <Bgr, byte>(width, height);
            var bytes = new byte[image.Data.Length];

            Rng.GetBytes(bytes);
            Buffer.BlockCopy(bytes, 0, image.Data, 0, bytes.Length);

            double average  = bytes.Average(x => (double)x);
            double delta    = Math.Sqrt(bytes.Average(x => (double)x * x) - average * average);
            double minValue = bytes.Min(x => (double)x);
            double maxValue = bytes.Max(x => (double)x);
            var    sb       = new StringBuilder();

            sb.AppendLine(string.Format("Length {0}", image.Data.Length));
            sb.AppendLine(string.Format("Average {0}", average));
            sb.AppendLine(string.Format("Delta {0}", delta));
            sb.AppendLine(string.Format("minValue {0}", minValue));
            sb.AppendLine(string.Format("maxValue {0}", maxValue));
            Console.WriteLine(sb.ToString());

            using (var blurBuilder = new BlurBuilder(filterStep))
                image = blurBuilder.Blur(image);

            Buffer.BlockCopy(image.Data, 0, bytes, 0, bytes.Length);

            double average1  = bytes.Average(x => (double)x);
            double delta1    = Math.Sqrt(bytes.Average(x => (double)x * x) - average1 * average1);
            double minValue1 = bytes.Min(x => (double)x);
            double maxValue1 = bytes.Max(x => (double)x);
            var    sb1       = new StringBuilder();

            sb1.AppendLine(string.Format("Length {0}", image.Data.Length));
            sb1.AppendLine(string.Format("Average {0}", average1));
            sb1.AppendLine(string.Format("Delta {0}", delta1));
            sb1.AppendLine(string.Format("minValue {0}", minValue1));
            sb1.AppendLine(string.Format("maxValue {0}", maxValue1));
            Console.WriteLine(sb1.ToString());

            Assert.IsTrue(delta1 < delta);
        }
Exemplo n.º 6
0
        public void BlurTestMethod()
        {
            const int width = 100;
            const int height = 100;
            const int filterStep = 1;

            var image = new Image<Bgr, byte>(width, height);
            var bytes = new byte[image.Data.Length];

            Rng.GetBytes(bytes);
            Buffer.BlockCopy(bytes, 0, image.Data, 0, bytes.Length);

            double average = bytes.Average(x => (double) x);
            double delta = Math.Sqrt(bytes.Average(x => (double) x*x) - average*average);
            double minValue = bytes.Min(x => (double) x);
            double maxValue = bytes.Max(x => (double) x);
            var sb = new StringBuilder();
            sb.AppendLine(string.Format("Length {0}", image.Data.Length));
            sb.AppendLine(string.Format("Average {0}", average));
            sb.AppendLine(string.Format("Delta {0}", delta));
            sb.AppendLine(string.Format("minValue {0}", minValue));
            sb.AppendLine(string.Format("maxValue {0}", maxValue));
            Console.WriteLine(sb.ToString());

            using (var blurBuilder = new BlurBuilder(filterStep))
                image = blurBuilder.Blur(image);

            Buffer.BlockCopy(image.Data, 0, bytes, 0, bytes.Length);

            double average1 = bytes.Average(x => (double) x);
            double delta1 = Math.Sqrt(bytes.Average(x => (double) x*x) - average1*average1);
            double minValue1 = bytes.Min(x => (double) x);
            double maxValue1 = bytes.Max(x => (double) x);
            var sb1 = new StringBuilder();
            sb1.AppendLine(string.Format("Length {0}", image.Data.Length));
            sb1.AppendLine(string.Format("Average {0}", average1));
            sb1.AppendLine(string.Format("Delta {0}", delta1));
            sb1.AppendLine(string.Format("minValue {0}", minValue1));
            sb1.AppendLine(string.Format("maxValue {0}", maxValue1));
            Console.WriteLine(sb1.ToString());

            Assert.IsTrue(delta1 < delta);
        }
Exemplo n.º 7
0
 /// <summary>
 ///     Blur bitmap with the Fastest Fourier Transform
 /// </summary>
 public CvBitmap(CvBitmap input, BlurBuilder builder)
     : base(builder.Blur(input).Data)
 {
 }
Exemplo n.º 8
0
        /// <summary>
        ///     Применение метода широкополосного сигнала
        ///     Внедрение данных в графический файл
        /// </summary>
        /// <param name="bbsOptions">Параметры алгоритма включая исходные данные</param>
        /// <returns>Графический файл с внедрёнными данными</returns>
        public static CvBitmap Pack(BbsOptions bbsOptions)
        {
            Debug.WriteLine(bbsOptions.ToString());

            var    key           = bbsOptions.Key;
            var    expandSize    = bbsOptions.ExpandSize;
            var    codeSize      = bbsOptions.EccCodeSize;
            var    dataSize      = bbsOptions.EccDataSize;
            double alpha         = bbsOptions.Alpha;
            double betta         = 0;
            var    dhtMode       = bbsOptions.DhtMode;
            var    autoAlpha     = bbsOptions.AutoAlpha;
            var    autoResize    = bbsOptions.AutoResize;
            var    maximumGamma  = bbsOptions.MaximumGamma;
            var    politicIndex  = bbsOptions.PoliticIndex;
            var    politicText   = bbsOptions.PoliticText;
            var    eccIndex      = bbsOptions.EccIndex;
            var    mixerIndex    = bbsOptions.MixerIndex;
            var    gammaIndex    = bbsOptions.GammaIndex;
            var    archiverIndex = bbsOptions.ArchiverIndex;
            var    barcodeIndex  = bbsOptions.BarcodeIndex;
            var    zipperIndex   = bbsOptions.ZipperIndex;
            var    filterStep    = bbsOptions.FilterStep;

            var sampleBitmap = bbsOptions.SampleBitmap;

            var      minSize       = sampleBitmap.Size;
            CvBitmap barcodeBitmap = null;

            try
            {
                using (var barcode = new Barcode(barcodeIndex)
                {
                    // indeces
                    ArchiverIndex = archiverIndex,
                    EccIndex = eccIndex,
                    MixerIndex = mixerIndex,
                    GammaIndex = gammaIndex,
                    // ints
                    ExpandSize = expandSize,
                    EccCodeSize = codeSize,
                    EccDataSize = dataSize,
                    // bools
                    DhtMode = dhtMode,
                    AutoAlpha = autoAlpha,
                    MaximumGamma = maximumGamma,
                    // strings
                    Key = key
                })
                {
                    // Формирование баркода с параметрами для используемых алгоритмов
                    barcodeBitmap = new CvBitmap(barcode.Encode());
                    var barcodeSize = barcodeBitmap.Size;
                    minSize.Width  = Math.Max(minSize.Width, 4 * barcodeSize.Width);
                    minSize.Height = Math.Max(minSize.Height, 4 * barcodeSize.Height);
                }
            }
            catch (ArgumentNullException exception)
            {
            }


            var bytes = Encoding.GetEncoding(0).GetBytes(bbsOptions.RtfText);

            Debug.WriteLine(string.Join("", bytes.Select(x => x.ToString("X02"))));

            //     В дополнение к самому методу широкополосного сигнала данные могут быть сжаты алгоритмом компрессии данных,
            //     добавлены коды исправления ошибок, последовательности бит могут размещаться в изображении не последовательно, а в
            //     соответствии с выбранным алгоритмом.
            IStreamTransform[] streamTransforms =
            {
                new Archiver(archiverIndex),          // Алгоритм сжатия данных
                new Envelope(),                       // Добавление конверта
                new Ecc(eccIndex, codeSize, dataSize) // Алгоритм коррекции ошибок
            };
            var input = new MemoryStream(bytes);

            Debug.WriteLine("input {0}", input.Length);
            foreach (var transform in streamTransforms)
            {
                using (var prev = input)
                    transform.Forward(prev, input = new MemoryStream());
                input.Seek(0, SeekOrigin.Begin);
                Debug.WriteLine("{0} {1}", transform, input.Length);
            }


            // для каждого бита сообщения нужно N пикселей носителя
            var inputLength    = input.Length;                           // Количество байт передаваемых данных
            var requiredLength = inputLength * expandSize * BitsPerByte; // Требуемое число пикселей
            var sampleSize     = sampleBitmap.Size;
            var sampleLength   = sampleBitmap.Length;
            var ratio          = Math.Sqrt(1 + (double)requiredLength / sampleLength);

            ratio          = Math.Max(ratio, (double)minSize.Width / sampleSize.Width);
            ratio          = Math.Max(ratio, (double)minSize.Height / sampleSize.Height);
            minSize.Width  = (int)Math.Max(minSize.Width, Math.Ceiling(ratio * sampleSize.Width));
            minSize.Height = (int)Math.Max(minSize.Height, Math.Ceiling(ratio * sampleSize.Height));

            CvBitmap bitmap;
            CvBitmap median;

            using (var stretchBuilder = new StretchBuilder(minSize))
                bitmap = new CvBitmap(sampleBitmap, stretchBuilder, autoResize);


            var length = bitmap.Length;
            var size   = bitmap.Size;

            if (requiredLength > length)
            {
                throw new Exception(
                          string.Format("Размер изображения недостаточен для сохранения данных {0}/{1}",
                                        requiredLength, sampleLength));
            }

            if (minSize.Width > size.Width || minSize.Height > size.Height)
            {
                throw new Exception(
                          string.Format(
                              "Размер изображения недостаточен для сохранения данных {0}x{1}/{2}x{3}",
                              size.Width, size.Height, minSize.Width, minSize.Height));
            }

            // Применение политики обработки неиспользуемых пикселей
            using (IStreamTransform streamTransform = new Politic(politicIndex, politicText, expandSize, bitmap))
                using (var prev = input)
                    streamTransform.Forward(prev, input = new MemoryStream());

            input.Seek(0, SeekOrigin.Begin);
            Debug.WriteLine("input {0}", input.Length);

            // Внедрения в передаваемое изображение баркода с настроечными параметрами для используемых алгоритмов
            if (barcodeBitmap != null)
            {
                bitmap.DrawCopyright(barcodeBitmap);
            }

            using (var builder = new BlurBuilder(filterStep))
                median = new CvBitmap(bitmap, builder);

            using (var reader = new BinaryReader(input))
            {
                var data = reader.ReadBytes((int)input.Length);
                Debug.WriteLine(string.Join("", data.Select(x => x.ToString("X02"))));

                var index        = new int[length];
                var colors       = new double[length];
                var medianColors = new double[length];

                var gamma = new byte[maximumGamma
                    ? ((length + BitsPerByte - 1) / BitsPerByte)
                    : ((expandSize + BitsPerByte - 1) / BitsPerByte)];

                using (var builder = new Mixer(mixerIndex, key))
                    builder.GetInts(index);
                using (var builder = new Gamma(gammaIndex, key))
                    builder.GetBytes(gamma);

                var bitmapDataContainer = dhtMode ? new HartleyOfBitmap(bitmap) : (IDataContainer)bitmap;
                bitmapDataContainer.Select(index, colors);

                var medianDataContainer = dhtMode
                    ? new HartleyOfBitmap(median)
                    : (IDataContainer)median;
                medianDataContainer.Select(index, medianColors);

                Debug.Assert(dhtMode || colors.All(x => x >= 0));
                Debug.Assert(dhtMode || medianColors.All(x => x >= 0));

                // Рассчёт весов пикселей
                var middle  = medianColors.Average();
                var weight  = medianColors.Select(x => F / (F + Math.Abs(x - middle))).ToArray();
                var average = weight.Average();
                weight = weight.Select(x => x / average).ToArray();

                if (autoAlpha)
                {
                    // Вычисление параметров из характеристик отправляемых данных

                    var delta = colors.Zip(medianColors, (x, y) => (x - y)).Zip(weight, (x, y) => x * y).ToArray();

                    var e1 = delta.Average(x => x);
                    var e2 = delta.Average(x => x * x);

                    bbsOptions.Alpha = (int)Math.Ceiling(alpha = Math.Sqrt(e2 - e1 * e1));

                    // Использование псевдослучайной последовательности с характеристиками приближенными к равновероятной, для кодирования
                    // данных, позволяет сохранить среднюю яркость пикселей у исходного графического изображения и у изображения,
                    // содержащего внедрённые данные
                    // Однако при прямом и дословном применении алгоритма средняя яркость пикселей могла бы иметь смещение относительно средней яркости у исходного изображения
                    // Поэтому производим статистическую оценку такого смещения и вводим её в качестве компенсирующего слагаемого в алгоритм

                    // Вычисление количества единиц в исходных данных и псевдослучайной последовательности
                    double trueData  = BitCounter.Count(data);
                    double trueGamma = BitCounter.Count(gamma);

                    // Вычисление количества нулей в исходных данных и псевдослучайной последовательности
                    var falseData  = (long)data.Length * BitsPerByte - trueData;
                    var falseGamma = (long)gamma.Length * BitsPerByte - trueGamma;

                    // Вычисление оценки количества единиц и нулей при смешивании исходных данных и псевдослучайной последовательности
                    var trueCount  = trueGamma * falseData + falseGamma * trueData;
                    var falseCount = trueGamma * trueData + falseGamma * falseData;

                    betta = ((falseCount - trueCount) * alpha / (trueCount + falseCount));

                    Debug.WriteLine("alpha = {0} betta = {1}", alpha, betta);
                }

                using (var bbSignals = new BbSignals(expandSize, maximumGamma))
                {
                    var delta = new double[colors.Length];
                    bbSignals.Combine(delta, data, gamma, alpha, betta);
                    delta  = delta.Zip(weight, (x, y) => x * y).ToArray();
                    colors = colors.Zip(delta, (x, y) => (x + y)).ToArray();
                }

                bitmapDataContainer.Replace(index, colors);
                return(bbsOptions.OutputBitmap = bitmap);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        ///     Применение метода широкополосного сигнала
        ///     Извлечение данных из графического файла
        /// </summary>
        /// <param name="bbsOptions">Параметры алгоритма включая графический файл с внедрёнными данными</param>
        /// <returns>Извлечённые данные</returns>
        public static string Unpack(BbsOptions bbsOptions)
        {
            Debug.WriteLine(bbsOptions.ToString());

            var    key            = bbsOptions.Key;
            var    expandSize     = bbsOptions.ExpandSize;
            var    codeSize       = bbsOptions.EccCodeSize;
            var    dataSize       = bbsOptions.EccDataSize;
            var    filterStep     = bbsOptions.FilterStep;
            var    eccIndex       = bbsOptions.EccIndex;
            var    mixerIndex     = bbsOptions.MixerIndex;
            var    gammaIndex     = bbsOptions.GammaIndex;
            var    archiverIndex  = bbsOptions.ArchiverIndex;
            var    zipperIndex    = bbsOptions.ZipperIndex;
            double alpha          = bbsOptions.Alpha;
            double betta          = 0;
            var    dhtMode        = bbsOptions.DhtMode;
            var    autoAlpha      = bbsOptions.AutoAlpha;
            var    maximumGamma   = bbsOptions.MaximumGamma;
            var    extractBarcode = bbsOptions.ExtractBarcode;

            var bitmap = bbsOptions.InputBitmap;

            if (extractBarcode)
            {
                using (var barcode = new Barcode(bitmap.Bitmap))
                {
                    // Извлечение параметров из внедрённого в изображение баркода
                    // и использование этих извлечённых параметров для используемых алгоритмов
                    barcode.Decode();
                    archiverIndex = barcode.ArchiverIndex;
                    eccIndex      = barcode.EccIndex;
                    mixerIndex    = barcode.MixerIndex;
                    gammaIndex    = barcode.GammaIndex;
                    // ints
                    expandSize = barcode.ExpandSize;
                    codeSize   = barcode.EccCodeSize;
                    dataSize   = barcode.EccDataSize;
                    // bools
                    dhtMode      = barcode.DhtMode;
                    autoAlpha    = barcode.AutoAlpha;
                    maximumGamma = barcode.MaximumGamma;
                    // strings
                    key = barcode.Key;

                    Debug.WriteLine(barcode.ToString());
                }
            }

            using (var builder = new BlurBuilder(filterStep))
                bbsOptions.MedianBitmap = new CvBitmap(bitmap, builder);
            var median = bbsOptions.MedianBitmap;

            var length = bitmap.Length;

            var index        = new int[length];
            var colors       = new double[length];
            var medianColors = new double[length];
            var data         = new byte[length / expandSize / BitsPerByte];

            using (var builder = new Mixer(mixerIndex, key))
                builder.GetInts(index);
            var gamma = new byte[maximumGamma
                ? ((length + BitsPerByte - 1) / BitsPerByte)
                : ((expandSize + BitsPerByte - 1) / BitsPerByte)];

            using (var builder = new Gamma(gammaIndex, key))
                builder.GetBytes(gamma);

            var bitmapDataContainer = dhtMode ? new HartleyOfBitmap(bitmap) : (IDataContainer)bitmap;

            bitmapDataContainer.Select(index, colors);

            var medianDataContainer = dhtMode ? new HartleyOfBitmap(median) : (IDataContainer)median;

            medianDataContainer.Select(index, medianColors);

            Debug.Assert(dhtMode || colors.All(x => x >= 0));
            Debug.Assert(dhtMode || medianColors.All(x => x >= 0));

            // Рассчёт весов пикселей
            var middle  = medianColors.Average();
            var weight  = medianColors.Select(x => F / (F + Math.Abs(x - middle))).ToArray();
            var average = weight.Average();

            weight = weight.Select(x => x / average).ToArray();

            var delta = colors.Zip(medianColors, (x, y) => (x - y)).Zip(weight, (x, y) => x * y).ToArray();

            if (autoAlpha)
            {
                // Вычисление параметров из характеристик полученных данных

                var e1 = delta.Average(x => x);
                var e2 = delta.Average(x => x * x);
                betta            = e1;
                bbsOptions.Alpha = (int)Math.Ceiling(alpha = Math.Sqrt(e2 - e1 * e1));

                Debug.WriteLine("alpha = {0} betta = {1}", alpha, betta);
            }

            using (var bbSignals = new BbSignals(expandSize, maximumGamma))
                bbSignals.Extract(delta, data, gamma, alpha, betta);

            Debug.WriteLine(string.Join("", data.Select(x => x.ToString("X02"))));

            //     В дополнение к самому методу широкополосного сигнала данные могут быть сжаты алгоритмом компрессии данных,
            //     добавлены коды исправления ошибок, последовательности бит могут размещаться в изображении не последовательно, а в
            //     соответствии с выбранным алгоритмом.
            IStreamTransform[] streamTransforms =
            {
                new Ecc(eccIndex, codeSize, dataSize), // Алгоритм коррекции ошибок
                new Envelope(),                        // Извлечение из конверта
                new Archiver(archiverIndex)            // Алгоритм извлечения из сжатого архива
            };

            var input = new MemoryStream(data);

            Debug.WriteLine("input {0}", input.Length);
            foreach (var transform in streamTransforms)
            {
                using (var prev = input)
                    transform.Backward(prev, input = new MemoryStream());
                input.Seek(0, SeekOrigin.Begin);
                Debug.WriteLine("{0} {1}", transform, input.Length);
            }
            using (var reader = new BinaryReader(input))
            {
                var bytes = reader.ReadBytes((int)input.Length);
                Debug.WriteLine(string.Join("", bytes.Select(x => x.ToString("X02"))));
                return(bbsOptions.RtfText = Encoding.GetEncoding(0).GetString(bytes));
            }
        }
Exemplo n.º 10
0
        private const int BitsPerByte = 8; // Количество битов в байте

        /// <summary>
        ///     Применение метода широкополосного сигнала
        ///     Внедрение данных в графический файл
        /// </summary>
        /// <param name="bbsOptions">Параметры алгоритма включая исходные данные</param>
        /// <returns>Графический файл с внедрёнными данными</returns>
        public static CvBitmap Pack(BbsOptions bbsOptions)
        {
            Debug.WriteLine(bbsOptions.ToString());

            string key           = bbsOptions.Key;
            int    expandSize    = bbsOptions.ExpandSize;
            int    codeSize      = bbsOptions.EccCodeSize;
            int    dataSize      = bbsOptions.EccDataSize;
            int    alpha         = bbsOptions.Alpha;
            int    betta         = 0;
            bool   autoAlpha     = bbsOptions.AutoAlpha;
            bool   autoResize    = bbsOptions.AutoResize;
            bool   maximumGamma  = bbsOptions.MaximumGamma;
            int    politicIndex  = bbsOptions.PoliticIndex;
            string politicText   = bbsOptions.PoliticText;
            int    eccIndex      = bbsOptions.EccIndex;
            int    mixerIndex    = bbsOptions.MixerIndex;
            int    gammaIndex    = bbsOptions.GammaIndex;
            int    archiverIndex = bbsOptions.ArchiverIndex;
            int    barcodeIndex  = bbsOptions.BarcodeIndex;
            int    filterStep    = bbsOptions.FilterStep;

            CvBitmap sampleBitmap = bbsOptions.SampleBitmap;

            Size     minSize       = sampleBitmap.Size;
            CvBitmap barcodeBitmap = null;

            try
            {
                using (var barcode = new Barcode(barcodeIndex)
                {
                    ArchiverIndex = archiverIndex,
                    EccIndex = eccIndex,
                    MixerIndex = mixerIndex,
                    GammaIndex = gammaIndex,
                    ExpandSize = expandSize,
                    EccCodeSize = codeSize,
                    EccDataSize = dataSize,
                    MaximumGamma = maximumGamma,
                    Key = key,
                })
                {
                    // Формирование баркода с параметрами для используемых алгоритмов
                    barcodeBitmap = new CvBitmap(barcode.Encode());
                    Size barcodeSize = barcodeBitmap.Size;
                    minSize.Width  = Math.Max(minSize.Width, 4 * barcodeSize.Width);
                    minSize.Height = Math.Max(minSize.Height, 4 * barcodeSize.Height);
                }
            }
            catch (ArgumentNullException exception)
            {
            }


            byte[] bytes = Encoding.Default.GetBytes(bbsOptions.RtfText);
            Debug.WriteLine(string.Join("", bytes.Select(x => x.ToString("X02"))));

            //     В дополнение к самому методу широкополосного сигнала данные могут быть сжаты алгоритмом компрессии данных,
            //     добавлены коды исправления ошибок, последовательности бит могут размещаться в изображении не последовательно, а в
            //     соответствии с выбранным алгоритмом.
            IStreamTransform[] streamTransforms =
            {
                new Archiver(archiverIndex),          // Алгоритм сжатия данных
                new Envelope(),                       // Добавление конверта
                new Ecc(eccIndex, codeSize, dataSize) // Алгоритм коррекции ошибок
            };
            var input = new MemoryStream(bytes);

            Debug.WriteLine("input {0}", input.Length);
            foreach (IStreamTransform transform in streamTransforms)
            {
                using (MemoryStream prev = input)
                    transform.Forward(prev, input = new MemoryStream());
                input.Seek(0, SeekOrigin.Begin);
                Debug.WriteLine("{0} {1}", transform, input.Length);
            }


            // для каждого бита сообщения нужно N байт носителя
            long   inputLength    = input.Length;                           // Количество байт передаваемых данных
            long   requiredLength = inputLength * expandSize * BitsPerByte; // Требуемое число пикселей
            Size   sampleSize     = sampleBitmap.Size;
            long   sampleLength   = sampleBitmap.Length;
            double ratio          = Math.Sqrt(1 + (double)requiredLength / sampleLength);

            ratio          = Math.Max(ratio, (double)minSize.Width / sampleSize.Width);
            ratio          = Math.Max(ratio, (double)minSize.Height / sampleSize.Height);
            minSize.Width  = (int)Math.Max(minSize.Width, Math.Ceiling(ratio * sampleSize.Width));
            minSize.Height = (int)Math.Max(minSize.Height, Math.Ceiling(ratio * sampleSize.Height));

            CvBitmap bitmap;

            using (var stretchBuilder = new StretchBuilder(minSize))
                bitmap = new CvBitmap(sampleBitmap, stretchBuilder, autoResize);

            long length = bitmap.Length;
            Size size   = bitmap.Size;

            if (requiredLength > length)
            {
                throw new Exception(
                          string.Format("Размер изображения недостаточен для сохранения данных {0}/{1}",
                                        requiredLength, sampleLength));
            }

            if (minSize.Width > size.Width || minSize.Height > size.Height)
            {
                throw new Exception(
                          string.Format(
                              "Размер изображения недостаточен для сохранения данных {0}x{1}/{2}x{3}",
                              size.Width, size.Height, minSize.Width, minSize.Height));
            }

            // Внедрения в передаваемое изображение баркода с настроечными параметрами для используемых алгоритмов
            if (barcodeBitmap != null)
            {
                bitmap.DrawCopyright(barcodeBitmap);
            }

            using (IStreamTransform streamTransform = new Politic(politicIndex, politicText, expandSize, bitmap))
                using (MemoryStream prev = input)
                    streamTransform.Forward(prev, input = new MemoryStream());
            input.Seek(0, SeekOrigin.Begin);
            Debug.WriteLine("input {0}", input.Length);
            using (var reader = new BinaryReader(input))
            {
                byte[] data = reader.ReadBytes((int)input.Length);
                Debug.WriteLine(string.Join("", data.Select(x => x.ToString("X02"))));

                var index  = new int[length];
                var colors = new byte[length];
                var cw     = new byte[length];

                var gamma = new byte[maximumGamma
                    ? ((length + BitsPerByte - 1) / BitsPerByte)
                    : ((expandSize + BitsPerByte - 1) / BitsPerByte)];

                using (var builder = new Mixer(mixerIndex, key))
                    builder.GetInts(index);
                using (var builder = new Gamma(gammaIndex, key))
                    builder.GetBytes(gamma);

                bitmap.Select(index, colors);

                if (autoAlpha)
                {
                    using (var blurBuilder = new BlurBuilder(filterStep))
                        using (var median = new CvBitmap(bitmap, blurBuilder))
                        {
                            if (barcodeBitmap != null)
                            {
                                median.DrawCopyright(barcodeBitmap);
                            }
                            var medianColors = new byte[length];
                            median.Select(index, medianColors);

                            double e1 = colors.Zip(medianColors,
                                                   (x, y) => (int)x - (int)y).Average(x => (double)x);
                            double e2 = colors.Zip(medianColors,
                                                   (x, y) => (int)x - (int)y).Average(x => (double)x * x);

                            alpha            = (int)Math.Sqrt(e2 - e1 * e1);
                            bbsOptions.Alpha = alpha;

                            // Вычисление оценки смещение яркости относительно средней яркости исходного изображения при прямом и дословном применении алгоритма
                            // Построение массивов, содержащих статистическую информацию о исходных данных и псевдослучайной последовательности
                            // То есть построение гистограмм исходных данных и псевдослучайной последовательности
                            var countData  = new int[256];
                            var countGamma = new int[256];
                            foreach (byte ch in data)
                            {
                                countData[ch]++;
                            }
                            foreach (byte ch in gamma)
                            {
                                countGamma[ch]++;
                            }

                            // Построение массива, где каждый элемент содержит количество ненулевых бит в бинарном разложении индекса элемента
                            var count = new int[256];
                            count[0] = 0;
                            for (int k = 1; k < 256; k <<= 1)
                            {
                                for (int i = 0; i < k; i++)
                                {
                                    count[k + i] = count[i] + 1;
                                }
                            }

                            // Использование псевдослучайной последовательности с характеристиками приближенными к равновероятной, для кодирования
                            // данных, позволяет сохранить среднюю яркость пикселей у исходного графического изображения и у изображения,
                            // содержащего внедрённые данные
                            // Однако при прямом и дословном применении алгоритма средняя яркость пикселей могла бы иметь смещение относительно средней яркости у исходного изображения
                            // Поэтому производим статистическую оценку такого смещения и вводим её в качестве компенсирующего слагаемого в алгоритм

                            // Вычисление количества единиц в исходных данных и псевдослучайной последовательности
                            double trueData  = count.Zip(countData, (x, y) => (double)((long)x * y)).Sum();
                            double trueGamma = count.Zip(countGamma, (x, y) => (double)((long)x * y)).Sum();

                            // Вычисление количества нулей в исходных данных и псевдослучайной последовательности
                            double falseData  = (long)data.Length * BitsPerByte - trueData;
                            double falseGamma = (long)gamma.Length * BitsPerByte - trueGamma;

                            // Вычисление оценки количества единиц и нулей при смешивании исходных данных и псевдослучайной последовательности
                            double trueCount  = trueGamma * falseData + falseGamma * trueData;
                            double falseCount = trueGamma * trueData + falseGamma * falseData;

                            betta            = (int)((falseCount - trueCount) * alpha / (trueCount + falseCount));
                            bbsOptions.Alpha = alpha;
                        }
                }

                using (var bbSignals = new BbSignals(expandSize, maximumGamma))
                    bbSignals.Combine(colors, data, gamma, alpha, betta, cw);
                bitmap.Replace(index, cw);
                return(bbsOptions.OutputBitmap = bitmap);
            }
        }
Exemplo n.º 11
0
        /// <summary>
        ///     Применение метода широкополосного сигнала
        ///     Извлечение данных из графического файла
        /// </summary>
        /// <param name="bbsOptions">Параметры алгоритма включая графический файл с внедрёнными данными</param>
        /// <returns>Извлечённые данные</returns>
        public static string Unpack(BbsOptions bbsOptions)
        {
            Debug.WriteLine(bbsOptions.ToString());

            string key            = bbsOptions.Key;
            int    expandSize     = bbsOptions.ExpandSize;
            int    codeSize       = bbsOptions.EccCodeSize;
            int    dataSize       = bbsOptions.EccDataSize;
            int    filterStep     = bbsOptions.FilterStep;
            int    eccIndex       = bbsOptions.EccIndex;
            int    mixerIndex     = bbsOptions.MixerIndex;
            int    gammaIndex     = bbsOptions.GammaIndex;
            int    archiverIndex  = bbsOptions.ArchiverIndex;
            int    alpha          = bbsOptions.Alpha;
            int    betta          = 0;
            bool   autoAlpha      = bbsOptions.AutoAlpha;
            bool   maximumGamma   = bbsOptions.MaximumGamma;
            bool   extractBarcode = bbsOptions.ExtractBarcode;

            CvBitmap bitmap = bbsOptions.InputBitmap;

            if (extractBarcode)
            {
                using (var barcode = new Barcode(bitmap.Bitmap))
                {
                    // Извлечение параметров из внедрённого в изображение баркода
                    // и использование этих извлечённых параметров для используемых алгоритмов
                    barcode.Decode();
                    archiverIndex = barcode.ArchiverIndex;
                    eccIndex      = barcode.EccIndex;
                    mixerIndex    = barcode.MixerIndex;
                    gammaIndex    = barcode.GammaIndex;
                    expandSize    = barcode.ExpandSize;
                    codeSize      = barcode.EccCodeSize;
                    dataSize      = barcode.EccDataSize;
                    maximumGamma  = barcode.MaximumGamma;
                    key           = barcode.Key;
                }
            }

            using (var builder = new BlurBuilder(filterStep))
                bbsOptions.MedianBitmap = new CvBitmap(bitmap, builder);
            CvBitmap median = bbsOptions.MedianBitmap;

            long length = bitmap.Length;

            var index        = new int[length];
            var colors       = new byte[length];
            var medianColors = new byte[length];
            var data         = new byte[length / expandSize / BitsPerByte];

            using (var builder = new Mixer(mixerIndex, key))
                builder.GetInts(index);
            var gamma = new byte[maximumGamma
                ? ((length + BitsPerByte - 1) / BitsPerByte)
                : ((expandSize + BitsPerByte - 1) / BitsPerByte)];

            using (var builder = new Gamma(gammaIndex, key))
                builder.GetBytes(gamma);
            bitmap.Select(index, colors);
            median.Select(index, medianColors);

            if (autoAlpha)
            {
                double e1 = colors.Zip(medianColors,
                                       (x, y) => (int)x - (int)y).Average(x => (double)x);
                double e2 = colors.Zip(medianColors,
                                       (x, y) => (int)x - (int)y).Average(x => (double)x * x);
                betta            = (int)e1;
                alpha            = (int)Math.Sqrt(e2 - e1 * e1);
                bbsOptions.Alpha = alpha;
            }

            using (var bbSignals = new BbSignals(expandSize, maximumGamma))
                bbSignals.Extract(colors, medianColors, gamma, alpha, betta, data);
            Debug.WriteLine(string.Join("", data.Select(x => x.ToString("X02"))));

            //     В дополнение к самому методу широкополосного сигнала данные могут быть сжаты алгоритмом компрессии данных,
            //     добавлены коды исправления ошибок, последовательности бит могут размещаться в изображении не последовательно, а в
            //     соответствии с выбранным алгоритмом.
            IStreamTransform[] streamTransforms =
            {
                new Ecc(eccIndex, codeSize, dataSize), // Алгоритм коррекции ошибок
                new Envelope(),                        // Извлечение из конверта
                new Archiver(archiverIndex)            // Алгоритм извлечения из сжатого архива
            };

            var input = new MemoryStream(data);

            Debug.WriteLine("input {0}", input.Length);
            foreach (IStreamTransform transform in streamTransforms)
            {
                using (MemoryStream prev = input)
                    transform.Backward(prev, input = new MemoryStream());
                input.Seek(0, SeekOrigin.Begin);
                Debug.WriteLine("{0} {1}", transform, input.Length);
            }
            using (var reader = new BinaryReader(input))
            {
                byte[] bytes = reader.ReadBytes((int)input.Length);
                Debug.WriteLine(string.Join("", bytes.Select(x => x.ToString("X02"))));
                return(bbsOptions.RtfText = Encoding.Default.GetString(bytes));
            }
        }
Exemplo n.º 12
0
        private static readonly int SIZE = 9;        //128;

        //512;

        private static void Main()
        {
            /*Vec3 v1 = new Vec3(1);
             * Console.WriteLine("v1 is: " + v1);
             * Vec3 v2 = new Vec3(1, 2, 4);
             * Console.WriteLine("v2 is: " + v2);
             * Console.WriteLine("Dot(v1, v2): " + Vec3.Dot(v1, v2));
             * Console.WriteLine("Cross(v1, v2): " + Vec3.Cross(v1, v2));
             * Console.WriteLine("Cross(v2, v1): " + Vec3.Cross(v2, v1));
             * Console.WriteLine("v1 + v2: " + ( v1 + v2 ));1
             * Console.WriteLine("v2 + v1: " + ( v2 + v1 ));
             * Console.WriteLine("v1 - v2: " + ( v1 - v2 ));
             * Console.WriteLine("v2 - v1: " + ( v2 - v1 ));
             * Console.WriteLine("v1 * v2: " + ( v1 * v2 ));
             * Console.WriteLine("v1 * 5: " + ( v1 * 5 ));
             * Console.WriteLine("v1 / 5: " + ( v1 / 5 ));
             * Console.WriteLine("v1 is: " + v1);
             * Console.WriteLine("v2 is: " + v2);
             *
             * Console.WriteLine("90 degrees: " + Angle.RightAngle.Vec2);
             *
             * Console.WriteLine("180 degrees: " + Angle.StraightAngle.AngleRaw);
             * Console.WriteLine("180 degrees: " + Angle.StraightAngle.GetAngle(AngleFormat.Unit));
             * Console.WriteLine("180 degrees: " + Angle.StraightAngle.GetAngle(AngleFormat.Degrees));
             * Console.WriteLine("180 degrees: " + Angle.StraightAngle.GetAngle(AngleFormat.Radians));
             * Console.WriteLine("180 degrees: " + Angle.StraightAngle.Vec2);
             *
             * Console.WriteLine("Cross(v1, X): " + Vec3.Cross(v1, new Vec3(1, 0, 0)));
             * Console.WriteLine("Cross(v1, Y): " + Vec3.Cross(v1, new Vec3(0, 1, 0)));
             * Console.WriteLine("Cross(v1, Z): " + Vec3.Cross(v1, new Vec3(0, 0, 1)));
             * Console.WriteLine("v1.CrossX: " + v1.CrossX);
             * Console.WriteLine("v1.CrossY: " + v1.CrossY);
             * Console.WriteLine("v1.CrossZ: " + v1.CrossZ);
             *
             * Sector<float> sectorFloat = new Sector<float>(new Coordinate(0, 0), 1, 1);
             * sectorFloat[0, 0] = 0;
             * sectorFloat[1, 0] = 50;
             *
             * Console.WriteLine("should be 12.5: " + sectorFloat.ValueAt(0.5f, 0.5f));
             */
            Stopwatch sw = new Stopwatch();

            Console.WriteLine("Stopwatch Started");
            Console.WriteLine("Building...");
            sw.Start();

            LandscapeBuilder landscapeBuilder = new LandscapeBuilder();

            landscapeBuilder["random"] = new RandomBuilder()
            {
                Seed = 6
            };
            landscapeBuilder["vec2"] = new Vec2FieldBuilder()
            {
                SourceID = "random", Magnitude = Constants.SQRT_2_OVER_2_FLOAT
            };
            landscapeBuilder["mem1"] = new MemoryBuilder <Vec2>()
            {
                SourceID = "vec2"
            };
            landscapeBuilder["perlin"] = new ParlinGroupBuiler()
            {
                Vec2FieldID = "mem1", UpperTargetScale = SCALE, MaxPerlinScale = SCALE / 4, DeltaFactor = 0.625f, ScaleStep = 1.5f, RetFactor = 1f, BottomUp = false, OffsetGlobal = new Coordinate(64, 64), LowerTargetScale = 2
            };
            //landscapeBuilder["mem2"] = new MemoryBuilder<float>() { SourceID = "perlin" };
            //0.5325f
            landscapeBuilder["mem2"] = new MemoryBuilder <float>()
            {
                SourceID = "perlin"
            };
            landscapeBuilder["HE"] = new HydraulicErosionBuilder()
            {
                SourceID               = "mem2",
                LayeringPower          = 7,
                CoverageFactor         = 1 / 4f,
                BrushRadius            = 4,
                StepLength             = 2f,
                Gravity                = 4,
                OutputFactor           = 0.2f,
                Friction               = 0.5f,
                SedimentCapacityFactor = 1.125f,
                MinModification        = 0.01f,
                ErodeSpeed             = 0.5f,
                DepositSpeed           = 0.125f,
                SedimentFactor         = 2,
            };
            landscapeBuilder["HEmem"] = new MemoryStrictSectoringBuilder <float>()
            {
                SourceID = "HE", SectorSize = 32
            };
            landscapeBuilder["HEmblur"] = new BlurBuilder {
                SourceID = "HEmem"
            };
            landscapeBuilder["finalInterpol"] = new InterpolatorBuilder {
                SourceID = "HEmblur", Scale = 2
            };
            landscapeBuilder["finalblur"] = new BlurBuilder {
                SourceID = "finalInterpol"
            };
            landscapeBuilder["fianlMem"] = new MemoryBuilder <float>()
            {
                SourceID = "HEmblur"
            };
            landscapeBuilder["HEinv"] = new FloatAdderBuilder()
            {
                Sources = new string[] { "fianlMem" }, RetFactor = -1
            };
            landscapeBuilder["HEdiff"] = new FloatAdderBuilder()
            {
                Sources = new string[] { "HEinv", "mem2" }, RetFactor = 2
            };
            landscapeBuilder["output"] = new HeightMapImageOutputterBuilder()
            {
                SourceID = "mem2", Layers = 3, Size = 100, Min = -1, Max = 1
            };

            //landscapeBuilder["blur1"] = new BlurBuilder() { SourceID = "mem2" };
            //landscapeBuilder["brush"] = new BrushTestBuilder();

            Landscape landscape = landscapeBuilder.Build();

            //string xml = landscapeBuilder.XML;
            //Console.WriteLine(xml);
            //landscapeBuilder.XML = xml;
            //Console.WriteLine(landscapeBuilder.XML);
            Console.WriteLine("Elapsed={0}", sw.Elapsed);
            Console.WriteLine("Computing...");

            sw.Restart();
            Algorithm <float>  outputPerlin    = landscape.GetAlgorithm <float>("mem2");
            Algorithm <float>  outputHE        = landscape.GetAlgorithm <float>("fianlMem");
            Algorithm <float>  outputdiff      = landscape.GetAlgorithm <float>("HEdiff");
            Outputter <Bitmap> bitmapOutputter = landscape.GetOutputter <Bitmap>("output");

            RequstSector request = new RequstSector(new Coordinate(0, 0), SIZE, SIZE);

            //Sector<float> sectordiff = outputdiff.GetSector(request);
            //Sector<float> sectorHE = outputHE.GetSector(request);
            //Sector<float> sectorPerlin = outputPerlin.GetSector(request);

            sw.Stop();
            Console.WriteLine("Elapsed={0}", sw.Elapsed);
            //Console.WriteLine("Press \"Enter\" to save", sw.Elapsed);
            //Console.ReadKey();

            int width  = request.Width_units * 3;
            int height = request.Height_units;

            Bitmap bmp = bitmapOutputter.GetObject(new Coordinate());

            Console.WriteLine("Saving...");
            bmp.Save("D:\\output.png", ImageFormat.Png);

            //Console.WriteLine("min: " + min + " max: " + max + " avg: " + (double) total / (width * height) + " errors: " + errors);
            Console.WriteLine("Saved");
            GC.Collect();
            Console.ReadKey();
        }