Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.50/30: Рейтинг темы: голосов - 30, средняя оценка - 4.50
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676

Добавить к коду подсчет яркостей

22.09.2020, 09:49. Показов 7764. Ответов 124
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C#
1
2
3
4
5
6
7
8
9
                foreach (var p in source)
                {
                    //get pixel from dithering matrix
                    var dithPixel = dith[p.X % dith.Width, p.Y % dith.Height].GetBrightness();
                    //get pixel from source image
                    var pixel = source[p].GetBrightness();
                    //compare
                    res[p] = pixel >= dithPixel ? Color.White : Color.Black;
                }
Вот такой код есть из темы.
Хочу расширить код подсчитывая количество значений яркости dithPixel например в виде структуры [Value, Count], но не могу вспомнить как это сделать через хеши (именованные массивы).
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.09.2020, 09:49
Ответы с готовыми решениями:

Добавить к коду подсчет вызовов функции
помогите добавить подсчет вызовов функции,вообще не знаю,как symbol = 's' height = 3 width = 3 counter = 3 def dec1(f): ...

Подсчёт суммы значений в ячейках по столбцу по коду товара
Для упрощения. Вот есть две таблицы. Первая с двумя столбцами и кучей строк. 1 столбец в ней - это код товара, 2 столбец - цена. Товар...

Добавить комментарии к коду
Здравствуйте. Кто сможет закомментировать код? <script language="JavaScript"> var elements = document.URL.substr(8).split(/\/|\\/); ...

124
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
01.10.2020, 15:53  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от belalugoci Посмотреть сообщение
pictureBox0.Image = ImageSource = (Bitmap)Image.FromFile(@"C:\Users\e.n.b\ Pictures\Deepin\cristina-gottardi-wndpWTiDuT0-unsplash.jpg");
здесь на домашнем Ci5-3570 = 0.1603
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
02.10.2020, 07:15  [ТС]
добавил эквализацию
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        internal static BrightnesData Equalization(BrightnesData data)
        {
            int height = data.Brightnes.GetLength(1);
            int width = data.Brightnes.GetLength(0);
            int k = 255; // k = 255;
            float[] h = new float[k + 1]; // h: array [0 .. k] of double;
            for (int i = 0; i <= k; i++) // for i := 0 to k do
                h[i] = 0; //h[i] := 0;
            for (int j = 0; j < width; j++) // for i := 0 to self.Height - 1 do
                for (int i = 0; i < height; i++) // for j := 0 to self.Width - 1 do
                {
                    int index = (int)(k * data.Brightnes[j, i] / 510);
                    h[index] = h[index] + 1;// h[round(k * self.Pixels[i, j])] := h[round(k * self.Pixels[i, j])] + 1;
                }
            for (int i = 0; i <= k; i++) // for i := 0 to k do
                h[i] = h[i] / (height * width); // h[i] := h[i] / (self.Height * self.Width);
            for (int i = 1; i <= k; i++) // for i := 1 to k do
                h[i] = h[i - 1] + h[i]; // h[i] := h[i - 1] + h[i];
            for (int j = 0; j < width; j++) // for i := 0 to self.Height - 1 do
                for (int i = 0; i < height; i++) // for j := 0 to self.Width - 1 do
                    data.Brightnes[j, i] = (int)(h[(int)(k * data.Brightnes[j, i] / 510)] * 510); // self.Pixels[i, j] := h[round(k * self.Pixels[i, j])];
 
            return data;
        }
переделал пример реализации на паскале, он напротив каждой строки в комментарии. Во вложении результат работы:
1) слева оригинал, справа - эквализированное изображение
2) левое верхнее - оригинал, левое нижнее - дизеринг оригинала, правое верхнее - эквализированное, правое нижнее - дизеринг эквализированного
Миниатюры
Добавить к коду подсчет яркостей   Добавить к коду подсчет яркостей  
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
02.10.2020, 10:15  [ТС]
смотрю многие ссылаются на библиотеку AForge для работы с изображениями...

Добавлено через 1 час 31 минуту
Цитата Сообщение от belalugoci Посмотреть сообщение
добавил эквализацию
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        internal static BrightnesData Equalization(BrightnesData data)
        {
            int height = data.Brightnes.GetLength(1);
            int width = data.Brightnes.GetLength(0);
            int k = 510;
            float[] h = new float[k + 1];
            for (int i = 0; i <= k; i++)
                h[i] = 0;
            for (int j = 0; j < width; j++)
                for (int i = 0; i < height; i++)
                {
                    int index = (int)(data.Brightnes[j, i]);
                    h[index] = h[index] + 1;
                }
            int hw = height * width;
            for (int i = 0; i <= k; i++)
                h[i] = h[i] / hw;
            for (int i = 1; i <= k; i++)
                h[i] = h[i - 1] + h[i];
            for (int j = 0; j < width; j++)
                for (int i = 0; i < height; i++)
                    data.Brightnes[j, i] = (int)(h[(int)(data.Brightnes[j, i])] * k);
            return data;
        }
Немного изменил, так как в BrightnesData разрешение яркостей в 511 элементов, то и приведение к 256 в эквализации заменил на 511. (кстати почему 511?)
думаю блок
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
            float[] h = new float[k + 1];
            for (int i = 0; i <= k; i++)
                h[i] = 0;
            for (int j = 0; j < width; j++)
                for (int i = 0; i < height; i++)
                {
                    int index = (int)(data.Brightnes[j, i]);
                    h[index] = h[index] + 1;
                }
            int hw = height * width;
            for (int i = 0; i <= k; i++)
                h[i] = h[i] / hw;
            for (int i = 1; i <= k; i++)
                h[i] = h[i - 1] + h[i];
Уместнее перенести в GetBrightnes.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
02.10.2020, 10:17
C#
1
2
3
            float[] h = new float[k + 1];
            for (int i = 0; i <= k; i++)
                h[i] = 0;
Зачем тут цикл, если массив и так при создании инициализирован нулями?
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
02.10.2020, 10:30
Цитата Сообщение от belalugoci Посмотреть сообщение
кстати почему 511?
Яркость по методу MS (а нам надо получать эквивалент) определяется как среднее между минимальным и максимальным из значений байтов R, G, B.

Чтобы не накапливать ошибок округления, я вместо определения среднего (это полу сумма) сохраняю полную сумму.

Сумма двух байт может дать минимальное значение 0.
Максимальное 255 + 255 = 510.

Количество значений включительно в диапазоне 0-510 равно 511.
1
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
02.10.2020, 10:48  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Зачем тут цикл, если массив и так при создании инициализирован нулями?
потому что брутфорс копиед.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
02.10.2020, 10:48
belalugoci, Из поста #69
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Так и есть!
MS как всегда "отличилась":
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        public float GetBrightness() {
            float r = (float)R / 255.0f;
            float g = (float)G / 255.0f;
            float b = (float)B / 255.0f;
 
            float max, min;
 
            max = r; min = r;
 
            if (g > max) max = g;
            if (b > max) max = b;
 
            if (g < min) min = g;
            if (b < min) min = b;
 
            return(max + min) / 2;
        }
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
02.10.2020, 10:51  [ТС]
кстати, почему при работе кода жрётся >500 мегабайт оперативки?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
02.10.2020, 11:55
Цитата Сообщение от belalugoci Посмотреть сообщение
кстати, почему при работе кода жрётся >500 мегабайт оперативки?
BrightnesData - занимает (примерно) по 4 байта на каждый пиксель.
Bitmap - как минимум столько же. Но возможно и больше.
Каждый созданный экземпляр BrightnesData или рисунока Bitmap (после фильтра) хранится в памяти.
Если он нигде не используется (на него не осталось ссылок), то со временем мусорщик очистит память от него.
Но когда это произойдёт - знает только ОС.

Всё остальное - это Net.

Добавлено через 3 минуты
В методе GetBrightnes(Bitmap) моего варианта, создаётся ещё и локальный байтовый буфер тоже размером 4 байта на пиксель.
После выхода из метода он отправляется в мусор.
Но сколько он там будет висеть - решать мусорщику.

Добавлено через 3 минуты
belalugoci, а в целом имейте ввиду, что из программ общего применения - Фоторедакторы это одни из самых требовательных приложений к ёмкости ОЗУ и скорости процессора.
Всегда очень прожорливы в отношении памяти.
Более требовательны только Видеоредакторы.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
02.10.2020, 12:38  [ТС]
Метод Собеля по определению границ прикрутил - ляпота... Потом прикручу объединение с эквализайией и дизерингом, но это уже на следующей неделе. В общем получается лучше чем я думал.
Миниатюры
Добавить к коду подсчет яркостей   Добавить к коду подсчет яркостей  
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
03.10.2020, 16:01
Цитата Сообщение от belalugoci Посмотреть сообщение
Метод Собеля по определению границ прикрутил - ляпота... Потом прикручу объединение с эквализайией и дизерингом, но это уже на следующей неделе. В общем получается лучше чем я думал.
Возможно использование полной суммы лучше подойдёт для ваших целей.
Проверьте:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
using System;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace Forms2009
{
    public partial class Form1 : Form
    {
        //private const int BrightnessRange = 2 * 255 + 1;
        private const int BrightnessRange = 3 * 255 + 1;
 
        Bitmap ImageSource,
               ImageResult25, ImageResult50, ImageResult75;
 
        PictureBox pictureBox0 = new PictureBox(),
            pictureBox1 = new PictureBox(),
            pictureBox2 = new PictureBox(),
            pictureBox3 = new PictureBox();
        public Form1()
        {
            InitializeComponent();
 
            // Установка параметров рисунков
            pictureBox0.SizeMode = pictureBox1.SizeMode = pictureBox2.SizeMode = pictureBox3.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox0.Parent = pictureBox1.Parent = pictureBox2.Parent = pictureBox3.Parent = this;
 
            // Подключение прослушки к изменению размера Формы
            SizeChanged += FormSizeChanged;
 
            // Разворачивание Формы
            WindowState = FormWindowState.Maximized;
 
            // Чтение рисунка, его сохранение в поле и вывод на форму.
            pictureBox0.Image = ImageSource = (Bitmap)Image.FromFile(@"C:\Users\EldHa\OneDrive\Изображения\ashim-d-silva-WeYamle9fDM-unsplash.jpg");
            //pictureBox1.Image = ImageSource = (Bitmap)Image.FromFile(@"C:\Users\EldHa\OneDrive\Изображения\Ярлыки\HardForum — копия.gif");
 
            // Получение матрицы яркости в истинных единицах и массива статистики яркостей
            BrightnesData brightnes = GetBrightnes(ImageSource);
 
            // Получение чёрно-белых рисунков из матрицы яркостей с разной долей отсечки точек
            pictureBox1.Image = ImageResult25 = BlackWhiteImage(brightnes, 0.25);
            pictureBox2.Image = ImageResult50 = BlackWhiteImage(brightnes, 0.5);
            pictureBox3.Image = ImageResult75 = BlackWhiteImage(brightnes, 0.75);
        }
 
        /// <summary>Метод адаптации размеров рисунков под изменение размеров Формы.</summary>
        private void FormSizeChanged(object sender, EventArgs e)
        {
            int width = Width / 2 - 5;
            int height = Height / 2 - 5;
 
            pictureBox0.Width = pictureBox1.Width = pictureBox2.Width = pictureBox3.Width = width;
            pictureBox0.Height = pictureBox1.Height = pictureBox2.Height = pictureBox3.Height = height;
 
            pictureBox0.Left = 0;
            pictureBox0.Top = 0;
 
            pictureBox1.Left = width + 10;
            pictureBox1.Top = 0;
 
            pictureBox2.Left = 0;
            pictureBox2.Top = height + 10;
 
            pictureBox3.Left = width + 10;
            pictureBox3.Top = height + 10;
 
        }
 
        /// <summary>Контейнер для возврата из метода связанных данных по яркости изображения.</summary>
        public class BrightnesData
        {
            /// <summary>Массив Яркостей.</summary>
            public int[,] Brightnes { get; }
            /// <summary>Массив кортежей яркостей и количества точек с такой яркостью.</summary>
            public (int brightne, int count)[] BrightnesCounts { get; }
            /// <summary>Создание экземпляра типа.</summary>
            /// <param name="brightnes">Массив Яркостей.</param>
            /// <param name="brightnesCounts">Массив кортежей яркостей и количества точек с такой яркостью.</param>
            public BrightnesData(int[,] brightnes, (int brightne, int count)[] brightnesCounts)
            {
                Brightnes = brightnes;
                BrightnesCounts = brightnesCounts;
            }
        }
 
        /// <summary>Преобразует пиксельное цветное изображение в массив in[,] яркостей.</summary>
        /// <param name="bmp">Цветное изображение в формате bmp.</param>
        /// <param name="tasksCount">Количество потоков для расчёта. По умолчанию - 10 потоков.</param>
        /// <returns>Контейнер <see cref="BrightnesData"/> с двумя свойствами:<br/>
        /// <see cref="BrightnesData.Brightnes"/> - Матрица int[,] полной яркостей пикселей.<br/>
        /// Значения полных яркостей в истинных целых единицах.<br/>
        /// Отличаются от значений <see cref="Color.GetBrightness"/> примерно в 765 раз.<br/>
        /// и <see cref="BrightnesData.BrightnesCounts"/> - Отсортированный массив<br/>
        /// имеющихся различных яркостей и количества точек с такой яркостю.</returns>
        public static BrightnesData GetBrightnes(Bitmap bmp, int tasksCount = 10)
        {
            // Получение байтового массива рисунка. Байты получаются в последовательности Format32bppArgb
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            int stride = bmpData.Stride;
            byte[] bmpBytes = new byte[stride * bmp.Height];
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, bmpBytes, 0, bmpBytes.Length);
            bmp.UnlockBits(bmpData);
 
            // Создание массива яркостей и массива для подсчёта количества точек с каждой яркостью
            int[,] brightnes = new int[bmp.Height, bmp.Width];
            int[] brightnesCounts = new int[BrightnessRange];
 
            // Инициализация локальных переменных и структуры для передачи данных в задачи
            int height = bmp.Height;
            int width = bmp.Width;
            Task<int[]>[] tasks = new Task<int[]>[tasksCount];
            RowCalkData data = new RowCalkData()
            {
                length = height / tasksCount,
                bmpBytes = bmpBytes,
                brightnes = brightnes
            };
 
            // Если количество строк не кратно количеству потоков, то определятся сколь "лишних строк"
            int mod = height % tasksCount;
 
            // Количество переданных в обработку строк
            int counRow = 0;
 
            // Цикл для создания и запуска задач
            for (int num = 0; num < tasksCount; num++)
            {
                // Копирование контейнера с данными для передачи в задачу.
                RowCalkData _data = data;
 
                // Задание начальной строки для работы задачи
                _data.rowBegin = counRow;
 
                // Если не все "лишние строки" посланы в обработку, то добавление одной в создаваемую задачу.
                if (mod-- > 0)
                    _data.length++;
                counRow += _data.length;
 
                // Создание, запуск задачи и запоминание её в массиве
                tasks[num] = Task<int[]>.Factory.StartNew(RowCalk, _data);
            }
 
            // Цикл ожидания завершения каждой задачи.
            while ((tasks = tasks.Where(t => t != null).ToArray()).Length > 0)
            {
                // Обработка возвращённых задачей данных и удаление задачи из массива
                int num = Task.WaitAny(tasks);
                for (int i = 0; i < BrightnessRange; i++)
                    brightnesCounts[i] += tasks[num].Result[i];
                tasks[num] = null;
            }
 
            // LINQ создающий массив кортежей со статистикой по матрице яркостей.
            (int brightne, int count)[] brightnesCountsSort = brightnesCounts
                .Select((cnt, br) => (brightne: br, count: cnt))
                .Where(pr => pr.count > 0)
                .OrderBy(pr => pr.count)
                .ToArray();
 
 
            return new BrightnesData(brightnes, brightnesCountsSort);
        }
 
        /// <summary>Структура для передачи данных в задачу.</summary>
        struct RowCalkData
        {
            /// <summary>Начальная строка для обработка.</summary>
            public int rowBegin;
            /// <summary>Длина диапазона обрабатываемых строк.</summary>
            public int length;
            /// <summary>Байтовый массив изображения.</summary>
            public byte[] bmpBytes;
            /// <summary>Матрица яркостей.</summary>
            public int[,] brightnes;
        }
 
        // Mетод для расчёта яркостей диапазона строк
        static int[] RowCalk(object obj)
        {
            // Получение структуры данных из нетипизированного параметра
            RowCalkData data = (RowCalkData)obj;
 
            // Ширина изображения
            int width = data.brightnes.GetLength(1);
 
            // Смещение в байтовом массиве
            int k = data.rowBegin * width * 4;
 
            // Строка следующего диапазона - она не должна обрабатываться
            int rowEnd = data.rowBegin + data.length;
 
            // Создание массива статистики по диапазону обрабатываемому в задаче
            int[] brightnesCounts = new int[BrightnessRange];
 
            // Локальные переменные для промежуточного хранения данных в цикле.
            //int brightne, r, g, b, min, max;
            int brightne;
 
            // Циклы по строкам диапазона и по всем колонкам
            for (int row = data.rowBegin; row < rowEnd; row++)
            {
                for (int col = 0; col < width; col++)
                {
                    //// Подсчёт яркости по алгоритму MS
                    //r = data.bmpBytes[k++];
                    //g = data.bmpBytes[k++];
                    //b = data.bmpBytes[k++];
                    //min = max = r;
                    //if (g > max) max = g;
                    //if (b > max) max = b;
 
                    //if (g < min) min = g;
                    //if (b < min) min = b;
 
                    //brightne = min + max;
 
                    // Подсчёт полной яркости
                    brightne = data.bmpBytes[k++] + data.bmpBytes[k++] + data.bmpBytes[k++];
 
                    // Запоминание яркости и корректировка статистики
                    brightnesCounts[data.brightnes[row, col] = brightne]++;
 
                    k++;
                }
            }
            return brightnesCounts;
        }
 
        /// <summary>Конвертация Матрицы яркости в чёрно белое изображение.</summary>
        /// <param name="data">Матрица яркости и массив статистики.</param>
        /// <param name="part">Доля срезаемых точек от общего их количества.</param>
        /// <returns>Чёрно белое изображение.</returns>
        internal static Bitmap BlackWhiteImage(BrightnesData data, double part)
        {
            // Размеры матрицы
            int height = data.Brightnes.GetLength(0);
            int width = data.Brightnes.GetLength(1);
 
            // Создание байтового массива для изображения
            byte[] argb = new byte[data.Brightnes.Length * 4];
 
            // Уровень срезаемой яркости
            int avbr = 0;
            // Количество срезаемых точек
            double countPixels = 0;
 
            // Цикл по массиву статистики отсортированному по возрастанию яркости
            foreach (var item in data.BrightnesCounts.OrderBy(x => x.brightne))
            {
                // Запоминание яркости
                avbr = item.brightne;
                // Добавление количества точек с этой яркостью
                countPixels += item.count;
 
                // Если количество срезаемых точек превышает заданную долю, то выход из цикла
                if (countPixels / data.Brightnes.Length > part)
                    break;
            }
 
            // Смещение в байтовом массиве
            int k = 0;
 
            // Цикл по всем точкам в массиве яркостей
            foreach (int brightne in data.Brightnes)
            {
                // Если у точки яркость выше определённой, то точка белая
                if (brightne > avbr)
                {
                    argb[k++] = 255;
                    argb[k++] = 255;
                    argb[k++] = 255;
                }
                // Иначе - чёрная
                else
                {
                    argb[k++] = 0;
                    argb[k++] = 0;
                    argb[k++] = 0;
                }
                // Задание байта прозрачности
                argb[k++] = 255;
            }
 
            // Создание нового рисунка с нужным размером и запись в него полученного байтового массива
            var result = new Bitmap(width, height);
            BitmapData bmpData = result.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            int stride = bmpData.Stride;
            System.Runtime.InteropServices.Marshal.Copy(argb, 0, bmpData.Scan0, argb.Length);
            result.UnlockBits(bmpData);
 
            return result;
        }
 
    }
}
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
04.10.2020, 15:20  [ТС]
Элд Хасп, два нижних imageBox обрезаются снизу, не пойму где косяк.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Возможно использование полной суммы лучше подойдёт для ваших целей.
а где изменения произошли? у меня проект изменён.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
04.10.2020, 15:29  [ТС]
в нижней части видно как усекается картинка
Миниатюры
Добавить к коду подсчет яркостей  
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
04.10.2020, 15:58
Цитата Сообщение от belalugoci Посмотреть сообщение
а где изменения произошли? у меня проект изменён.
В основном здесь:
C#
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
            for (int row = data.rowBegin; row < rowEnd; row++)
            {
                for (int col = 0; col < width; col++)
                {
                    //// Подсчёт яркости по алгоритму MS
                    //r = data.bmpBytes[k++];
                    //g = data.bmpBytes[k++];
                    //b = data.bmpBytes[k++];
                    //min = max = r;
                    //if (g > max) max = g;
                    //if (b > max) max = b;
 
                    //if (g < min) min = g;
                    //if (b < min) min = b;
 
                    //brightne = min + max;
 
                    // Подсчёт полной яркости
                    brightne = data.bmpBytes[k++] + data.bmpBytes[k++] + data.bmpBytes[k++];
 
                    // Запоминание яркости и корректировка статистики
                    brightnesCounts[data.brightnes[row, col] = brightne]++;
 
                    k++;
                }
            }
            return brightnesCounts;
Но повлекло ещё несколько изменений так как изменилось количество возможных значений яркости: было - 511, стало - 766:
C#
13
14
        //private const int BrightnessRange = 2 * 255 + 1;
        private const int BrightnessRange = 3 * 255 + 1;
Добавлено через 2 минуты
Цитата Сообщение от belalugoci Посмотреть сообщение
в нижней части видно как усекается картинка
Надо проверить размеры PictureBox.
Думаю картинка в них правильного размера.
А вот сами они целиком на форме не умещаются.

Добавлено через 6 минут
Цитата Сообщение от belalugoci Посмотреть сообщение
а где изменения произошли? у меня проект изменён.
Может даже имеет смыл считать по первоначальному алгоритму естественной яркости.
Он сильно не совпадает с методом MS, но зато лучше соответствует человеческому восприятию.
В нём диапазон значений яркостей 0 - 25500.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
05.10.2020, 06:29  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Надо проверить размеры PictureBox.
Здесь изменил.
C#
1
2
3
4
        private void FormSizeChanged(object sender, EventArgs e)
        {
            int width = Width / 2 - 20;
            int height = Height / 2 - 20;
Добавлено через 1 минуту
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Может даже имеет смыл считать по первоначальному алгоритму естественной яркости.
Может быть, но тогда резко подскакивает яркость изображения на выходе, возможно как яркость оно и правильно, но как визуальная составляющая уже неправильно. Возможно при работе с яркостями и имеет смысл пользоваться, но при выводе в Image преобразовывать.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
05.10.2020, 19:47
Цитата Сообщение от belalugoci Посмотреть сообщение
Может быть, но тогда резко подскакивает яркость изображения на выходе, возможно как яркость оно и правильно, но как визуальная составляющая уже неправильно. Возможно при работе с яркостями и имеет смысл пользоваться, но при выводе в Image преобразовывать.
Конечно, для разных целей нужны разные алгоритма.
То что лучше для вывода, не значит что лучше для того или иного фильтра.
Надо подбирать параметры.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
06.10.2020, 06:59  [ТС]
Вот еще такой расчет яркости нашел.
Миниатюры
Добавить к коду подсчет яркостей  
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
06.10.2020, 07:20  [ТС]
Если есть спортивный интерес в реализации CLAHE. Для меня задача сложная для понимания (речь даже не про реализацию, хотя с этим то тоже проблемы).
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
06.10.2020, 09:02  [ТС]
Цитата Сообщение от belalugoci Посмотреть сообщение
реализации CLAHE
поставил OpenCV, буду пробовать на нем.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
06.10.2020, 10:00
Цитата Сообщение от belalugoci Посмотреть сообщение
Вот еще такой расчет яркости нашел.
Это не просто другой метод расчёта яркости.
Это изменение цветового пространства.
Там совсем иной смысл вкладывается в значения.
Просто вставьте белый цвет (255,255,255) и посмотрите что выйдет.

Добавлено через 2 минуты
Цитата Сообщение от belalugoci Посмотреть сообщение
Если есть спортивный интерес в реализации CLAHE. Для меня задача сложная для понимания (речь даже не про реализацию, хотя с этим то тоже проблемы).
Она не сколько сложная (в реализации и понимании), а сколько объёмная.
Требует много времени на изучение (для понимания), реализации и отладки.

Добавлено через 1 минуту
Цитата Сообщение от belalugoci Посмотреть сообщение
поставил OpenCV, буду пробовать на нем.
Где есть возможность, надо стараться всегда использовать готовые библиотеки.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.10.2020, 10:00

Добавить комментарии к коду
нужно прокомментировать код mov ax,@data mov ds,ax mov cx,br mov si,offset mas xor ax, ax c1: xor ax, ax mov al, jmp...

Добавить комментарии к коду
Кто нибудь напишите подробный комментарий к коду ни СИ. Можно подробней по &quot;#define size 5&quot; и int a, a и a. ...

Добавить к коду многоадресный делегат
В иерархии, созданной в этой работе «Интерфейсы», добавить использование для проверки всех методов данного класса многоадресный делегат. ...

К готовому коду добавить процедуру
Суммы элементов каждого столбца матрицы X(m,n), имеющих значения в интервале Min…Max. Для столбца. (К ГОТОВОМУ КОДУ ДОБАВИТЬ ПРОЦЕДУРУ)...

К коду добавить вывод в консоль
Нужно вывести массив в консоль. Как ни пытался, то 0 выводит, то ошибки .586 .model flat,stdcall option casemap:none include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
120
Ответ Создать тему
Новые блоги и статьи
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru