Exemple #1
0
        private unsafe void ProcessPixelsByAction(Bitmap processedBitmap,
                                                  PixelAction actionForRgbPixels)
        {
            BitmapData bitmapData = processedBitmap.LockBits(
                new Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), ImageLockMode.ReadWrite,
                processedBitmap.PixelFormat);

            int   bytesPerPixel  = Bitmap.GetPixelFormatSize(processedBitmap.PixelFormat) / 8;
            int   heightInPixels = bitmapData.Height;
            int   widthInBytes   = bitmapData.Width * bytesPerPixel;
            byte *ptrFirstPixel  = (byte *)bitmapData.Scan0;

            /*Parallel.For(0, heightInPixels, y =>
             * {*/
            for (int y = 0; y < heightInPixels; y++)
            {
                byte *currentLine = ptrFirstPixel + (y * bitmapData.Stride);
                for (int x = 0; x < widthInBytes; x = x + bytesPerPixel)
                {
                    int blue  = currentLine[x];
                    int green = currentLine[x + 1];
                    int red   = currentLine[x + 2];
                    actionForRgbPixels.Invoke(ref red, ref green, ref blue);
                    currentLine[x]     = (byte)blue;
                    currentLine[x + 1] = (byte)green;
                    currentLine[x + 2] = (byte)red;
                }
            }

            //});
            processedBitmap.UnlockBits(bitmapData);
        }
Exemple #2
0
    public TIA(IReadyDevice cpu)
    {
        CPU = cpu;

        // create an array to call the proper delegate based on the current active pixel
        for (int horz = 0; horz < MAX_HORIZONTAL; horz++)
        {
            // add VSYNC
            for (int vert = 0; vert < 3; vert++)
            {
                pixelActions[horz, vert] = new PixelAction(VerticalSync);
            }

            // add VBLANK
            for (int vert = 3; vert < 40; vert++)
            {
                pixelActions[horz, vert] = new PixelAction(VerticalBlank);
            }

            for (int vert = 40; vert < 232; vert++)
            {
                // add HBLANK
                if (horz < END_OF_HBLANK)
                {
                    pixelActions[horz, vert] = new PixelAction(HorizontalBlank);
                }
                // viewable area
                else
                {
                    pixelActions[horz, vert] = new PixelAction(ViewableArea);
                }
            }

            // add OVERSCAN
            for (int vert = 232; vert < MAX_VERTICAL; vert++)
            {
                pixelActions[horz, vert] = new PixelAction(Overscan);
            }
        }
    }
Exemple #3
0
        /// <summary>
        /// Пересчитывает центральный пиксель региона
        /// </summary>
        /// <param name="action">Действие выполненной над пикселями региона перед пересчетом центрального пикселя</param>
        /// <param name="pixels">Массив пикселей, который были изменены в регионе перед пересчетом центрального пикселя</param>
        private void CalculateCenter(PixelAction action = PixelAction.none, Pixel[] pixels = null)
        {
            if (RegionPixels == null)
            {
                return;
            }

            // Извлекаем матрицу идентификаторов пикселей - в каждой строке находится идентификатор (координаты x и y пикселя)
            int[][] pixelIds = new int[RegionPixels.Count][];
            for (int i = 0; i < RegionPixels.Count; i++)
            {
                pixelIds[i] = RegionPixels[i].Id;
            }

            if (action == PixelAction.none)
            {
                // Инициализация массива сумм расстояний
                DistanceSums = new List <double>();
                for (int i = 0; i < RegionPixels.Count; i++)
                {
                    DistanceSums.Add(0.0);
                }

                // Ищем суммы расстояний от каждой точки до каждой точки региона
                for (int i = 0; i < RegionPixels.Count; i++)
                {
                    // Считаем сумму расстояний от точки i до всех остальных точек
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        if (i != j)
                        {
                            // Прибавляем к сумме расстояние от пикселя i до пикселя j
                            DistanceSums[i] += Math.Sqrt((pixelIds[i][0] - pixelIds[j][0]) * (pixelIds[i][0] - pixelIds[j][0]) +
                                                         (pixelIds[i][1] - pixelIds[j][1]) * (pixelIds[i][1] - pixelIds[j][1]));
                        }
                    }
                }
            }
            else if (action == PixelAction.add)
            {
                if (pixels == null)
                {
                    return;
                }

                // Добавляем новые элементы списка расстояний для новых пикселей и добавляем к уже существующим суммам новые расстояния
                int oldDistancesSumsCount = DistanceSums.Count; // Фиксируем количество пикселей, которые были в регионе до добавления
                for (int i = 0; i < pixels.Length; i++)
                {
                    int    oldDistancesIterator = 0;
                    double sum = 0.0;
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        double distance = Math.Sqrt((pixels[i].Id[0] - pixelIds[j][0]) * (pixels[i].Id[0] - pixelIds[j][0]) +
                                                    (pixels[i].Id[1] - pixelIds[j][1]) * (pixels[i].Id[1] - pixelIds[j][1]));

                        sum += distance;

                        // Если текущий пиксель относится еще к старым пикселям региона
                        if (oldDistancesIterator < oldDistancesSumsCount)
                        {
                            DistanceSums[j] += distance;
                        }

                        // Увеличиваем счетчик просмотренных пикселей
                        oldDistancesIterator++;
                    }

                    DistanceSums.Add(sum);
                }
            }
            else if (action == PixelAction.remove)
            {
                // В случае удаления пикселей, они удалены из списка пикселей и из списка расстояний уже до текущего момента

                if (pixels == null)
                {
                    return;
                }

                // Уменьшаем суммы расстояний оставшихся пикселей на величины расстояний до удаленных пикселей
                for (int i = 0; i < pixels.Length; i++)
                {
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        DistanceSums[j] -= Math.Sqrt((pixels[i].Id[0] - pixelIds[j][0]) * (pixels[i].Id[0] - pixelIds[j][0]) +
                                                     (pixels[i].Id[1] - pixelIds[j][1]) * (pixels[i].Id[1] - pixelIds[j][1]));
                    }
                }
            }
            else
            {
                return;
            }

            // Определение центрального пикселя региона
            double minSum = DistanceSums.Min();

            for (int i = 0; i < DistanceSums.Count; i++)
            {
                if (DistanceSums[i] == minSum)
                {
                    SpacialSenterId = pixelIds[i];
                    break;
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Пересчитывает все параметры для региона на основе параметров пикселей региона
        /// </summary>
        /// <param name="action">Действие, которое было произведено над пикселями перед вызовом функции</param>
        /// <param name="pixels">Массив пикселей, над которыми было произведено действие</param>
        public void CalculateParameters(PixelAction action = PixelAction.none, Pixel[] pixels = null)
        {
            if (RegionPixels == null)
            {
                return;
            }

            // если в регионе не осталось пикселей, то параметры региона сбрасываются
            if (RegionPixels.Count == 0)
            {
                SpacialSenterId[0] = SpacialSenterId[1] = -1;
                Area = 0;
                for (int i = 0; i < AverageTextureFeature.Length; i++)
                {
                    AverageTextureFeature[i] = 0;
                }
                for (int i = 0; i < AverageConditionalIntensityFeature.Length; i++)
                {
                    AverageConditionalIntensityFeature[i] = 0;
                }
                return;
            }

            if (action == PixelAction.none)
            {
                // расчет центра региона
                CalculateCenter();

                // расчет площади региона
                Area = RegionPixels.Count;

                // расчет среднего значения вектора текстурной характеристики для региона
                for (int i = 0; i < RegionPixels[0].TextureFeatures.Length; i++)
                {
                    double sum = 0.0;
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        sum += RegionPixels[j].TextureFeatures[i];
                    }
                    TextureFeatureSums[i]    = sum;
                    AverageTextureFeature[i] = sum / RegionPixels.Count;
                }

                // расчет среднего значения вектора интенсивности, полученного после условной фильтрации, для региона
                for (int i = 0; i < RegionPixels[0].ConditionalIntensityFeatures.Length; i++)
                {
                    double sum = 0.0;
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        sum += RegionPixels[j].ConditionalIntensityFeatures[i];
                    }
                    ConditionalIntensityFeatureSums[i]    = sum;
                    AverageConditionalIntensityFeature[i] = sum / RegionPixels.Count;
                }
            }
            else
            {
                if (pixels == null)
                {
                    return;
                }

                // расчет центра региона
                CalculateCenter(action, pixels);

                // расчет площади региона
                Area = RegionPixels.Count;

                // расчет среднего значения вектора текстурной характеристики для региона
                if (action == PixelAction.add)
                {
                    for (int i = 0; i < pixels.Length; i++)
                    {
                        for (int j = 0; j < RegionPixels[0].TextureFeatures.Length; j++)
                        {
                            TextureFeatureSums[j] += pixels[i].TextureFeatures[j];
                        }
                    }

                    for (int i = 0; i < RegionPixels[0].TextureFeatures.Length; i++)
                    {
                        AverageTextureFeature[i] = TextureFeatureSums[i] / RegionPixels.Count;
                    }
                }
                if (action == PixelAction.remove)
                {
                    for (int i = 0; i < pixels.Length; i++)
                    {
                        for (int j = 0; j < RegionPixels[0].TextureFeatures.Length; j++)
                        {
                            TextureFeatureSums[j] -= pixels[i].TextureFeatures[j];
                        }
                    }

                    for (int i = 0; i < RegionPixels[0].TextureFeatures.Length; i++)
                    {
                        AverageTextureFeature[i] = TextureFeatureSums[i] / RegionPixels.Count;
                    }
                }

                // расчет среднего значения вектора интенсивности, полученного после условной фильтрации, для региона
                if (action == PixelAction.add)
                {
                    for (int i = 0; i < pixels.Length; i++)
                    {
                        for (int j = 0; j < RegionPixels[0].ConditionalIntensityFeatures.Length; j++)
                        {
                            ConditionalIntensityFeatureSums[j] += pixels[i].ConditionalIntensityFeatures[j];
                        }
                    }

                    for (int i = 0; i < RegionPixels[0].ConditionalIntensityFeatures.Length; i++)
                    {
                        AverageConditionalIntensityFeature[i] = ConditionalIntensityFeatureSums[i] / RegionPixels.Count;
                    }
                }
                if (action == PixelAction.remove)
                {
                    for (int i = 0; i < pixels.Length; i++)
                    {
                        for (int j = 0; j < RegionPixels[0].ConditionalIntensityFeatures.Length; j++)
                        {
                            ConditionalIntensityFeatureSums[j] -= pixels[i].ConditionalIntensityFeatures[j];
                        }
                    }

                    for (int i = 0; i < RegionPixels[0].ConditionalIntensityFeatures.Length; i++)
                    {
                        AverageConditionalIntensityFeature[i] = ConditionalIntensityFeatureSums[i] / RegionPixels.Count;
                    }
                }
            }
        }
Exemple #5
0
			public static void ReadBC3AlphaBlock(long block, ref PixelColor[,] cache, int posX, PixelAction writeOut)
			{
				int alpha0 = (int)(block & 0xFF);
				int alpha1 = (int)((block >> 8) & 0xFF);
				bool isFirstGreater = alpha0 > alpha1;
				block = block >> 16;
				float[] alphaLookup = new float[8];
				for (int j = 0; j < 8; j++)
				{
					alphaLookup[j] = BC3GradientInterpolate(j, alpha0, alpha1, isFirstGreater) / 255f;
				}
				int i = 0;
				for (int y = 0; y < 4; y++)
				{
					for (int x = 0; x < 4; x++)
					{
						int alphaIndex = (int)(block >> (i * 3)) & 0x7;
						float alpha = alphaLookup[alphaIndex];
						i++;
						//cache[y, posX + x].a = alpha;
						writeOut(ref cache[y, posX + x], alpha);
					}
				}
			}
Exemple #6
0
        /// <summary>
        /// Пересчитывает центральный пиксель региона
        /// </summary>
        /// <param name="action">Действие выполненной над пикселями региона перед пересчетом центрального пикселя</param>
        /// <param name="pixels">Массив пикселей, который были изменены в регионе перед пересчетом центрального пикселя</param>
        private void CalculateCenter(PixelAction action = PixelAction.none, Pixel[] pixels = null)
        {
            if (RegionPixels == null)
                return;

            // Извлекаем матрицу идентификаторов пикселей - в каждой строке находится идентификатор (координаты x и y пикселя)
            int[][] pixelIds = new int[RegionPixels.Count][];
            for (int i = 0; i < RegionPixels.Count; i++)
                pixelIds[i] = RegionPixels[i].Id;

            if (action == PixelAction.none)
            {
                // Инициализация массива сумм расстояний
                DistanceSums = new List<double>();
                for (int i = 0; i < RegionPixels.Count; i++)
                    DistanceSums.Add(0.0);

                // Ищем суммы расстояний от каждой точки до каждой точки региона
                for (int i = 0; i < RegionPixels.Count; i++)
                {
                    // Считаем сумму расстояний от точки i до всех остальных точек
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        if (i != j)
                        {
                            // Прибавляем к сумме расстояние от пикселя i до пикселя j
                            DistanceSums[i] += Math.Sqrt((pixelIds[i][0] - pixelIds[j][0]) * (pixelIds[i][0] - pixelIds[j][0]) +
                                (pixelIds[i][1] - pixelIds[j][1]) * (pixelIds[i][1] - pixelIds[j][1]));
                        }
                    }
                }
            }
            else if (action == PixelAction.add)
            {
                if (pixels == null)
                    return;

                // Добавляем новые элементы списка расстояний для новых пикселей и добавляем к уже существующим суммам новые расстояния
                int oldDistancesSumsCount = DistanceSums.Count; // Фиксируем количество пикселей, которые были в регионе до добавления
                for (int i = 0; i < pixels.Length; i++)
                {
                    int oldDistancesIterator = 0;
                    double sum = 0.0;
                    for (int j = 0; j < RegionPixels.Count; j++)
                    {
                        double distance = Math.Sqrt((pixels[i].Id[0] - pixelIds[j][0]) * (pixels[i].Id[0] - pixelIds[j][0]) +
                            (pixels[i].Id[1] - pixelIds[j][1]) * (pixels[i].Id[1] - pixelIds[j][1]));

                        sum += distance;

                        // Если текущий пиксель относится еще к старым пикселям региона
                        if (oldDistancesIterator < oldDistancesSumsCount)
                            DistanceSums[j] += distance;

                        // Увеличиваем счетчик просмотренных пикселей
                        oldDistancesIterator++;
                    }

                    DistanceSums.Add(sum);
                }
            }
            else if (action == PixelAction.remove)
            {
                // В случае удаления пикселей, они удалены из списка пикселей и из списка расстояний уже до текущего момента

                if (pixels == null)
                    return;

                // Уменьшаем суммы расстояний оставшихся пикселей на величины расстояний до удаленных пикселей
                for (int i = 0; i < pixels.Length; i++)
                    for (int j = 0; j < RegionPixels.Count; j++)
                        DistanceSums[j] -= Math.Sqrt((pixels[i].Id[0] - pixelIds[j][0]) * (pixels[i].Id[0] - pixelIds[j][0]) +
                            (pixels[i].Id[1] - pixelIds[j][1]) * (pixels[i].Id[1] - pixelIds[j][1]));
            }
            else
                return;

            // Определение центрального пикселя региона
            double minSum = DistanceSums.Min();
            for (int i = 0; i < DistanceSums.Count; i++)
            {
                if (DistanceSums[i] == minSum)
                {
                    SpacialSenterId = pixelIds[i];
                    break;
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Пересчитывает все параметры для региона на основе параметров пикселей региона
        /// </summary>
        /// <param name="action">Действие, которое было произведено над пикселями перед вызовом функции</param>
        /// <param name="pixels">Массив пикселей, над которыми было произведено действие</param>
        public void CalculateParameters(PixelAction action = PixelAction.none, Pixel[] pixels = null)
        {
            if (RegionPixels == null)
                return;

            // если в регионе не осталось пикселей, то параметры региона сбрасываются
            if (RegionPixels.Count == 0)
            {
                SpacialSenterId[0] = SpacialSenterId[1] = -1;
                Area = 0;
                for (int i = 0; i < AverageTextureFeature.Length; i++)
                    AverageTextureFeature[i] = 0;
                for (int i = 0; i < AverageConditionalIntensityFeature.Length; i++)
                    AverageConditionalIntensityFeature[i] = 0;
                return;
            }

            if (action == PixelAction.none)
            {
                // расчет центра региона
                CalculateCenter();

                // расчет площади региона
                Area = RegionPixels.Count;

                // расчет среднего значения вектора текстурной характеристики для региона
                for (int i = 0; i < RegionPixels[0].TextureFeatures.Length; i++)
                {
                    double sum = 0.0;
                    for (int j = 0; j < RegionPixels.Count; j++)
                        sum += RegionPixels[j].TextureFeatures[i];
                    TextureFeatureSums[i] = sum;
                    AverageTextureFeature[i] = sum / RegionPixels.Count;
                }

                // расчет среднего значения вектора интенсивности, полученного после условной фильтрации, для региона
                for (int i = 0; i < RegionPixels[0].ConditionalIntensityFeatures.Length; i++)
                {
                    double sum = 0.0;
                    for (int j = 0; j < RegionPixels.Count; j++)
                        sum += RegionPixels[j].ConditionalIntensityFeatures[i];
                    ConditionalIntensityFeatureSums[i] = sum;
                    AverageConditionalIntensityFeature[i] = sum / RegionPixels.Count;
                }
            }
            else
            {
                if (pixels == null)
                    return;

                // расчет центра региона
                CalculateCenter(action, pixels);

                // расчет площади региона
                Area = RegionPixels.Count;

                // расчет среднего значения вектора текстурной характеристики для региона
                if (action == PixelAction.add)
                {
                    for (int i = 0; i < pixels.Length; i++)
                        for (int j = 0; j < RegionPixels[0].TextureFeatures.Length; j++)
                            TextureFeatureSums[j] += pixels[i].TextureFeatures[j];

                    for (int i = 0; i < RegionPixels[0].TextureFeatures.Length; i++)
                        AverageTextureFeature[i] = TextureFeatureSums[i] / RegionPixels.Count;
                }
                if (action == PixelAction.remove)
                {
                    for (int i = 0; i < pixels.Length; i++)
                        for (int j = 0; j < RegionPixels[0].TextureFeatures.Length; j++)
                            TextureFeatureSums[j] -= pixels[i].TextureFeatures[j];

                    for (int i = 0; i < RegionPixels[0].TextureFeatures.Length; i++)
                        AverageTextureFeature[i] = TextureFeatureSums[i] / RegionPixels.Count;
                }

                // расчет среднего значения вектора интенсивности, полученного после условной фильтрации, для региона
                if (action == PixelAction.add)
                {
                    for (int i = 0; i < pixels.Length; i++)
                        for (int j = 0; j < RegionPixels[0].ConditionalIntensityFeatures.Length; j++)
                            ConditionalIntensityFeatureSums[j] += pixels[i].ConditionalIntensityFeatures[j];

                    for (int i = 0; i < RegionPixels[0].ConditionalIntensityFeatures.Length; i++)
                        AverageConditionalIntensityFeature[i] = ConditionalIntensityFeatureSums[i] / RegionPixels.Count;
                }
                if (action == PixelAction.remove)
                {
                    for (int i = 0; i < pixels.Length; i++)
                        for (int j = 0; j < RegionPixels[0].ConditionalIntensityFeatures.Length; j++)
                            ConditionalIntensityFeatureSums[j] -= pixels[i].ConditionalIntensityFeatures[j];

                    for (int i = 0; i < RegionPixels[0].ConditionalIntensityFeatures.Length; i++)
                        AverageConditionalIntensityFeature[i] = ConditionalIntensityFeatureSums[i] / RegionPixels.Count;
                }
            }
        }