Closed plzombie closed 2 days ago
Добавить автодетект папки, куда установлен djvulibre
- done
Для определения цветного/серого пользуй S из HSL:
Si = max(RGBi)-min(RGBi)
S = (max(Si)+mean(Si))/2
S < T ? gray: color
Для определения ЧБ пользуй гистограмму серого:
G=gray(RGB)
H=histogram(G)
up=upper(H != 0)
low=lower(H != 0)
t = k*(up-low)
Sup = sum(H(up...up-t))
Slow = sum(H(low...low+t))
S = sum(H)
(Sup + Slow) > k*S ? BW : gray
PS: можешь испльзовать два отдельных коэффициента: klow (для чёрного) и kup (для белого). Или вообще только чёрный.
Опция -auto
добавлена и работает для простейшего случая, требует доработки.
Поддержку tiff я делать, скорее всего, не буду, так как libtiff сама по себе огромная библиотека (или надо брать libtiff от djvulibre)
По поводу количества потоков - проблема была в максимальном количестве waitable objects, равном MAXIMUM_WAIT_OBJECTS
. Исправил.
Отслеживай показатели насыщенности(S) и светлости(L) своих изображений:
int v_min = buf[i*(size_t)channels];
int v_max = v_min;
size_t ch = (channels < 3) ? channels : 3;
for(j = 1; j < ch; j++) {
int origin = buf[i*(size_t)channels+j];
v_min = (v_min < origin) ? v_min : origin;
v_max = (v_max < origin) ? origin : v_max;
}
int HSL_S = v_max - v_min;
int HSL_L = (v_max + v_min) / 2;
HSL_L
позволит тебе отсечь "белое" (допустим < 192
- "небелое"), и учитывать цветность HSL_S
только "небелых" пикселей.
PS: Порог (128) также рекомендую производить по HSL_L
.
Для анализа используй гистограммы:
uint64_t hist_L[256] = {0}, hist_S[256] = {0}, hist_SL[256] = {0};
int thres_L = 192;
hist_L[HSL_L]++;
hist_S[HSL_S]++;
hist_SL[HSL_S] += (HSL_L < thres_L) ? 1 : 0;
Для получения точечтой оценки используй "доминанту" гистограммы:
for (unsigned int i = 1; i < 256; i++)
{
histogram[i] += histogram[i - 1];
}
unsigned int ilow = 0;
for (unsigned int i = (256 >> 1); i > 0; i >>= 1)
{
uint64_t sum_max = 0;
unsigned int inew = ilow;
for (unsigned int j = ilow; j < (ilow + i); j++)
{
uint64_t const sum_low = (j > 0) ? histogram[j] : 0;
uint64_t const sum_high = histogram[j + i];
uint64_t const sum = sum_high - sum_low;
if (sum > sum_max)
{
inew = j;
sum_max = sum;
}
}
ilow = inew;
}
return ilow;
Помимо указанных манипуляций с HSL, можно также делать вспомогательное обесцвеченное изображение:
maxRGBi = max(Ri, Gi, Bi);
Ri = Gi = Bi = maxRGBi;
и применять различные метрики к двум изображениям. Ежели метрики простые (MSE, PSNR или корреляция), то можно обойтись без хранения вспомогательного изображения, вычисляя метрику "на лету".
По значению же метрики и производить классификацию серый/цветной. Желательно предусмотреть подавление фонового оттенка с помощью чего то, вроде фильтра GrayWorld.
Мне для первой итерации достаточно будет, чтобы он ч/б сканы, сохранённые в jpeg, корректно обрабатывал. То есть (берём модель HSV), условно, V близко к границам, а по S построим гистограмму, и чтобы большинство значений было в районе 0 (вычисляем порог от размера исходного изображения). А дальше уже можно делать адаптивный порог и прочее. Пока просто нет времени и настроения это доделывать. А потом уже можно для постеризованных изображений сделать детектор
Таски на версию 1.8
-automode
для автоматического выбора, использовать ли чб (чб или градации серого) или фото (цветные изображения) режим для каждой страницыОпционально