Страницы

Поиск по вопросам

Показаны сообщения с ярлыком обработка-изображений. Показать все сообщения
Показаны сообщения с ярлыком обработка-изображений. Показать все сообщения

вторник, 31 марта 2020 г.

Оставить только необходимые цвета с Bitmap

#c_sharp #net #изображения #bitmap #обработка_изображений


Как в Bitmap оставить только необходимые цвета пикселей, а остальные превратить,
например, в чёрный цвет?

Конечно, хотелось бы решение пошустрей.
    


Ответы

Ответ 1



Самый простой вариант - через GetPixel и SetPixel, но будет работать довольно медленно. Лучше использовать Scan0 и преобразовать картинку в массив intов, соответствующих цвету каждого пикселя - для этого подходит формат PixelFormat.Format32bppArgb - в нём цвета представлены 4 байтами и в intе тоже 4 байта. Ниже код обработки на VB.NET, его можно легко переписать на C#. Этот код заменяет один цвет на другой, но позволяет при сравнении игнорировать альфа-канал (и сохранять его при замене). Если нужно какое-либо ещё условие, то надо заменить соответствующее сравнение и присваивание. Public Shared Sub ReplaceColor(ByVal Bmp As Bitmap, ByVal OldColor As Color, ByVal NewColor As Color, Optional ByVal IgnoreAlpha As Boolean = False) Dim BmpData As BitmapData = Bmp.LockBits(New Rectangle(Nothing, Bmp.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb) Dim ArgbData(BmpData.Stride * BmpData.Height / 4 - 1) As Integer Dim Mask As Integer = If(IgnoreAlpha, (1 << 24) - 1, -1), NotMask As Integer = Not Mask Dim OldVal As Integer = ((((((CInt(OldColor.A) << 8) Or OldColor.R) << 8) Or OldColor.G) << 8) Or OldColor.B) And Mask Dim NewVal As Integer = ((((((CInt(NewColor.A) << 8) Or NewColor.R) << 8) Or NewColor.G) << 8) Or NewColor.B) And Mask Marshal.Copy(BmpData.Scan0, ArgbData, 0, ArgbData.Length) For Q As Integer = 0 To ArgbData.Length - 1 If (ArgbData(Q) And Mask) = OldVal Then ArgbData(Q) = (ArgbData(Q) And NotMask) Or NewVal Next Q Marshal.Copy(ArgbData, 0, BmpData.Scan0, ArgbData.Length) Bmp.UnlockBits(BmpData) End Sub

четверг, 23 января 2020 г.

Преобразовать массив пикселей в изображение в ios

#массивы #ios #objective_c #обработка_изображений


Доброго времени суток коллеги! У меня похоже не правильно работает эта функция. Мне
нужно:


Cоздать массив.
Установить массив в качестве изображения


Я написал примерно такую реализацию:

 //функция создаёт массив пикселей
- (void)ProccessImage { //352*288*4 = РАЗМЕР КАРТИНКИ

    unsigned char * buf = (unsigned char*)malloc(352*288*4);//выделить память под массив
    unsigned int *ibuf = (unsigned int *)buf; //

    for(int i = 0; i<352*288*4; i++){ //заполняем массив пикселей
        ibuf[i] = i|0x80808080;
    }
    UIImage*imageFromArray = [self convertBitmapRGBA8ToUIImage:buf withWidth:352
withHeight:288]; //создание изображения из массива пикселей.
    [ChangeImageView setImage:imageFromArray]; //установка  изображения в ImageView
        

    free(buf);
}

/*Функция по конвертации массива unsigned сhar в картинку. Дёрнута отсюда https://stackoverflow.com/questions/7650144/how-to-convert-bytearray-to-image-in-objective-c
*/
- (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer
                                withWidth:(int) width
                               withHeight:(int) height {


    size_t bufferLength = width * height * 4;
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength,
NULL);
    size_t bitsPerComponent = 8;
    size_t bitsPerPixel = 32;
    size_t bytesPerRow = 4 * width;

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    if(colorSpaceRef == NULL) {
        NSLog(@"Error allocating color space");
        CGDataProviderRelease(provider);
        return nil;
    }

    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    CGImageRef iref = CGImageCreate(width,
                                    height,
                                    bitsPerComponent,
                                    bitsPerPixel,
                                    bytesPerRow,
                                    colorSpaceRef,
                                    bitmapInfo,
                                    provider,   // data provider
                                    NULL,       // decode
                                    YES,            // should interpolate
                                    renderingIntent);

    uint32_t* pixels = (uint32_t*)malloc(bufferLength);

    if(pixels == NULL) {
        NSLog(@"Error: Memory not allocated for bitmap");
        CGDataProviderRelease(provider);
        CGColorSpaceRelease(colorSpaceRef);
        CGImageRelease(iref);
        return nil;
    }
  //  memcpy(pixels,buffer,bufferLength);
    CGContextRef context = CGBitmapContextCreate(pixels,
                                                 width,
                                                 height,
                                                 bitsPerComponent,
                                                 bytesPerRow,
                                                 colorSpaceRef,
                                                 bitmapInfo);

    if(context == NULL) {
        NSLog(@"Error context not created");
        free(pixels);
    }

    UIImage *image = nil;
    if(context) {

        CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);

        CGImageRef imageRef = CGBitmapContextCreateImage(context);

        // Support both iPad 3.2 and iPhone 4 Retina displays with the correct scale
        if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {
            float scale = [[UIScreen mainScreen] scale];
            image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
        } else {
            image = [UIImage imageWithCGImage:imageRef];
        }

        CGImageRelease(imageRef);   
        CGContextRelease(context);  
    }

    CGColorSpaceRelease(colorSpaceRef);
    CGImageRelease(iref);
    CGDataProviderRelease(provider);

    if(pixels) {
        free(pixels);
    }   
    return image;
}
//Конец функции по конвертации массива в изображение


В результате вышеуказанной реализации, устанавливается в imageView белый экран.

Вопрос: Как изменить реализацию так, чтобы в imageView был заполнен разноцветными
точками (чем-нибудь отличающимся от белого цвета)? 
    


Ответы

Ответ 1



Вот этот код генерирует мне картинку шума, если его вставить, например, во viewDidLoad int width = 500; int height = 500; size_t bufferLength = width * height * 4; uint8_t* pixels = (uint8_t*)malloc(bufferLength); for (int i = 0; i < bufferLength; i++) { pixels[i] = rand() % 255; } CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGContextRef ctx = CGBitmapContextCreate(pixels, width, height, 8, width * 4, space, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast); CGImageRef toCGImage = CGBitmapContextCreateImage(ctx); UIImage * uiimage = [[UIImage alloc] initWithCGImage:toCGImage]; CGImageRelease(toCGImage); CGColorSpaceRelease(space); CGContextRelease(ctx); free(pixels); UIImageView *imageView = [[UIImageView alloc] initWithImage:uiimage]; [self.view addSubview:imageView]; Для заполнения массива чем-то конкретным Есть формат пикселя, который определяется параметром kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast. Это значит RGBA, то есть каждый пиксель состоит из 4-х байтов, последовательно - красный (Red), зелёный (Green), синий (Blue), альфа (прозрачность). То есть, для установки конкретного массива пикселей, нужно забивать массив последовательностью из 4-х байт, последний из которых - 255 (то есть без прозрачности). Например: for (int i = 0; i < width * height; i++) { pixels[i * 4] = 100; //баланс красного pixels[i * 4 + 1] = 200; //баланс зеленого pixels[i * 4 + 2] = 50; //баланс синего pixels[i * 4 +3] = 255; //прозрачности }

пятница, 27 декабря 2019 г.

Поиск контуров на изображении

#cpp #opencv #обработка_изображений


Добрый вечер!

Работаю над задачей распознавания текста. 
Использую OpenCV.

Проблема такая: Есть текст(ниже), я хочу выделить каждый отдельный символ с помощью
метода: 

CVAPI(int)  cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,
                            int header_size CV_DEFAULT(sizeof(CvContour)),
                            int mode CV_DEFAULT(CV_RETR_LIST),
                            int method CV_DEFAULT(CV_CHAIN_APPROX_SIMPLE),
                            CvPoint offset CV_DEFAULT(cvPoint(0,0)));


Выделять(выделяю только внешние контуры - CV_RETR_EXTERNAL) и прорисовывать контуры
получается отлично, но проблема в том, что cvFindContours(...) возвращает найденные
контуры в произвольном порядке, но для моей задачи порядок очень важен. Вопрос в том,
как восстанавливать порядок обхода контуров или как сделать так, чтобы cvFindContours(...)
возвращал контуры в том порядке, который на картинке, а не так как ему вздумается?

При необходимости могу привести код.




    


Ответы

Ответ 1



Возможно ответ довольно банален, но можно просто отсортировать найденные прямоугольники по возрастанию x-координаты. Единственное, в чём могут возникнуть трудности - если текст многоэтажный, тут могу посоветовать из своей практики написать алгоритм анализа, наподобие трассировки целей, который начиная с самого левого контура будет искать следующего кандидата на слово из раствора по определённому углу (скажем, чтобы тангенс угла уплывания не превышал 45 градусов), и так пройтись по массиву прямоугольников, пока все не исчерпаем. В нашем проекте этот алгоритм идеально нас удовлетворяет. Думаю, даже в самой примитивной форме (как я описал выше) он будет отличным первым приближением.

вторник, 24 декабря 2019 г.

Ускорить загрузку сайта

#php #изображения #обработка_изображений


Здравствуйте. Как лучше организовать хранение фотографий? 

Как лучше сохранять изображения от пользователей (аватар, обложка страницы, посты
на стене и т.д.). В скольких размерах? Например, миниатюра 60х60, основное фото профиля
200х200, увеличенная версия - 1000х1000. Так? И как тогда это оптимизировать? В скрипте
если будет три фото сразу сохраняться, не слишком ли долго будет это происходить?
    


Ответы

Ответ 1



Если это каталог, то можно организовать lazy load. Плагин на jquery Второй вариант http-кэширование. Детальнее по нему (так же рекомендую почитать). Ну и делать тумбы. А разрешения вы сами подбираете под свой проект.

Ответ 2



Создавайте миниатюры по крону или через очереди. Тогда пользователь не будет ждать. Так же можно создавать миниатюру при первом обращении к ней. Например, если настроить nginx так, что бы на .jpg сначала проверялось наличие статики, а если ее нет, запрос отправлялся на скрипт, который генерит миниатюру и отдает ее в output. При следующем обращении будет отдаваться сразу статика

среда, 18 декабря 2019 г.

Распознавание образов с помощью нейронной сети

#java #cpp #нейронные_сети #обработка_изображений


Добрый вечер!

Пытаюсь распознавать изображения латинских букв(A,B,C,D,E,F,G,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)
и цифр(2,3,4,5,6,7,8,9)
размером 30x30 пикселей.
Архитектуру строю такую: 900 нейронов во входном слое, 100 нейронов в первом скрытом
слое, 90 нейронов во втором скрытом слое и 33 нейрона на выходе(т.к всего 33 класса
исходя из задачи - 25 букв и 8 цифр).
Таким образом, на выходе сети получается 33-размерный вектор который соответствует
какому-то классу.

Например: 

output: 
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - это двойка
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - тройка
......
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 - Буква Z


Входное изображение я преобразую в одномерный массив длины 30x30=900. Элементы массива
- значения 0 или 1(Исходное изображение строго чёрно-белое).
Получилось сформировать обучающую выборку на 752 элемента. На каждый класс(в среднем)
по 15-20 обучающих выборок. 

Использую алгоритм "Обратного распространения ошибки".

Очень долго происходит обучение, т.е на каждую эпоху обучения уходит очень много
времени порядка 5 секунд.
Скорость обучения выставляю в 0.1, постоянную момента устанавливаю в 0.5.

Вопрос вот в чём:
Как можно уменьшить количество нейронов на входе, чтобы было не 900, а 30 например.
Тогда, я думаю, будет быстро происходить обучение.
Т.к матрица изображения содержит 0 или 1, могу ли я произвести суммирование по строкам
или столбцам чтобы уменьшить количество нейронов?

Порекомендуйте так же подобрать архитектуру сети, по возможности.

Спасибо!
    


Ответы

Ответ 1



Такую проблему уже решили. Действительно она была актуальной,тк получается у вас слишком большое кол-во весов. Посчитайте на своём примере сами, их очень много. Решили проблему - придумав новую архитектуру, и в целом структуру нейронных сетей. Это сверточные нейросети (CNN), как раз предназначенные для распознавания образов. Если Вы НЕ из принципа взяли обычный перцептрон для этой задачи, то советую использовать CNN. Изучение этой сети стоит этого.

вторник, 26 ноября 2019 г.

C# и нейронные сети. С чего начать и в какую сторону смотреть?


Вопрос довольно общий, знаю.

Но я здесь немного уточню что бы было не так расплывчасто.


Интересует общая сжатая теория. С какой статьи лучше начать?
Интересуют актуальные библиотеки C#
Интересует приблизительная реализация уже созданной в нескольких вариациях идеи -
скармливаешь нейронке много изображений-пар: большое и маленькое. А нейронка учитс
делать из маленького большое и потом сравнивает сделанное большое и то большое которое ему скормили что бы понять что сделано не так. Какую нейронку лучше выбрать под даную задачу?
Не слишком ли сложная и на сколько вообще реальная задачка в 3, если учесть что я вообще ни бум-бум в нейронных сетях? 
Если задача непосильная для новичка в НС, то с каких задач-тренировок лучше начинать?

    


Ответы

Ответ 1



Одна из самых изысканных задач для НС приведена в этой статье, можно понять уровен проблематики и алгоритмов, которые задействуются для решений подобного класса задач и где действительно нужна НС. Примеры на OpenCV, что тоже замечательно. OpenCV - Библиотека с самой открытой лицензией и исходным кодом, написана на C++. Под C# есть wrapper'ы - EmguCV, OpenCV for Unity (можно и без Unity использовать). Есть адаптация для Visual Studio (C++), Objective C, Android Studio, Python. Даже для умеренно сложных задач НС обычно не нужна, и не очень даже применима - част приходится делать обработку видеопотока в реальном времени, а НС не самая быстрая штука далеко. По этой и еще ряду причин большинство разработчиков, уверенных поначалу что им нужна НС, от этой идеи впоследствии отказываются. Благо в OpenCV реализовано огромное количество алгоритмов на все случаи жизни - почти всё, что связано с обработкой видео и изображений там есть. После редактирования автором вопроса редактирую ответ :-) Большинство алгоритмов, реализованных в доступных пакетах, в основном предназначен для down-scaling, спрос на это очевиден - камера снимает в большом разрешении, а в Интернеты лучше постить, предварительно уменьшив фотку - этим пользуются все активные пользователи Интернетов и соцсетей. Up-scaling задача тоже достаточно хорошо проработана, просто спрос на нее несоизмерим меньше - тем не менее любой дизайнер отлично знает, что нужно делать, чтобы изображение можно было без проблем увеличивать - взять Corel Draw или другой пакет векторной графики, то есть сделать изображение векторным. Таким образом, если маленькое растровое изображение преобразовать в векторы, сделат up-scaling, мы скорее всего уже получим что-то интересное - обратите внимание на программ Potrace. В OpenCV готового для raster->vector ничего нет. Хотя из доступных инструментов и можно слепить что-то, врядли получится лучше чем у Potrace - всё-таки там люди занимались этой проблемой специально. Potrace идёт с исходниками и подробным описанием алгоритмов, так что простор для творчества полный :-) И самое интересное на десерт - пора взглянуть на ваше увеличенное изображение, путем сравнения с полученным в результате векторизации и up-scaling результатом выявит отклонения. Выявленные отклонения могут являться материалом для обучения НС. Например, можно пойти путем векторизации большого изображения, выявления соответствия кривых и сравнения их характеристик. По результатам обучения НС начнет выдавать некие рекомендации по коррекции кривых в произвольных изображениях. Может быть даже замахнуться на добавление кривых, типа дополнительных цветовых контуро градиента (хотя градиент в полученном изображении проще будет сгладить с помощью функций Blur и т.п.)

Ответ 2



Если хотите изучить математический аппарат нейронных сетей, то рекомендую начат с изучения перцептрона. Найти статьи по этому типу ИНС несложно. С библиотеками по нейронным сетям на C# довольно плохо дела обстоят. Для C# лучшая на мой взгляд, библиотека от Microsoft - Microsoft cognitive toolkit. (https://github.com/Microsoft/CNTK/wiki) Из минусов: нельзя обучать и строить модель сети в коде C#/.NET и пока реализация в бета-версии, так что могут быть баги. Из плюсов: легко строить различные сети с помощью скриптового языка Brainscript, есть поддержка вычислений/обучения модели на GPU от nVidia (на C#/.NET можно только вычислять), поддерживаются различные типы нейронных сетей. На гитхабе в разделе Wiki можете найти всю интересующую вас информацию и пример для реализации ИНС с помощью Microsoft cognitive toolkit в C#. Ещё можете посмотреть нейронные сети в математическом фреймворке Accord, но, насколько я помню, там не очень много возможностей и вычисления доступны только на ЦП. Конкретно для данной задачи я бы применил свёрточную нейронную сеть. http://engineering.flipboard.com/2015/05/scaling-convnets здесь даже можете посмотреть примерную архитектуру такой сети для поставленной вами задачи. Если нейронную сеть с нуля не собираетесь писать, то вполне посильная :) Попробуйте изучить для начала многослойный перцептрон и реализовать его, например для решения задачи XOR.

Ответ 3



Дополню предыдущие ответы относительно CNTK. Недавно вышедшая версия 2.2 имеет уж полноценный биндинг к C#. Соответственно, можно не только применять, но и обучать сеть, не переключаясь на Python или BrainScript.

среда, 13 марта 2019 г.

Преобразовать массив пикселей в изображение в ios

Доброго времени суток коллеги! У меня похоже не правильно работает эта функция. Мне нужно:
Cоздать массив. Установить массив в качестве изображения
Я написал примерно такую реализацию:
//функция создаёт массив пикселей - (void)ProccessImage { //352*288*4 = РАЗМЕР КАРТИНКИ
unsigned char * buf = (unsigned char*)malloc(352*288*4);//выделить память под массив unsigned int *ibuf = (unsigned int *)buf; //
for(int i = 0; i<352*288*4; i++){ //заполняем массив пикселей ibuf[i] = i|0x80808080; } UIImage*imageFromArray = [self convertBitmapRGBA8ToUIImage:buf withWidth:352 withHeight:288]; //создание изображения из массива пикселей. [ChangeImageView setImage:imageFromArray]; //установка изображения в ImageView
free(buf); }
/*Функция по конвертации массива unsigned сhar в картинку. Дёрнута отсюда https://stackoverflow.com/questions/7650144/how-to-convert-bytearray-to-image-in-objective-c */ - (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer withWidth:(int) width withHeight:(int) height {
size_t bufferLength = width * height * 4; CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL); size_t bitsPerComponent = 8; size_t bitsPerPixel = 32; size_t bytesPerRow = 4 * width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); if(colorSpaceRef == NULL) { NSLog(@"Error allocating color space"); CGDataProviderRelease(provider); return nil; }
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast; CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, // data provider NULL, // decode YES, // should interpolate renderingIntent);
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
if(pixels == NULL) { NSLog(@"Error: Memory not allocated for bitmap"); CGDataProviderRelease(provider); CGColorSpaceRelease(colorSpaceRef); CGImageRelease(iref); return nil; } // memcpy(pixels,buffer,bufferLength); CGContextRef context = CGBitmapContextCreate(pixels, width, height, bitsPerComponent, bytesPerRow, colorSpaceRef, bitmapInfo);
if(context == NULL) { NSLog(@"Error context not created"); free(pixels); }
UIImage *image = nil; if(context) {
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
// Support both iPad 3.2 and iPhone 4 Retina displays with the correct scale if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) { float scale = [[UIScreen mainScreen] scale]; image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp]; } else { image = [UIImage imageWithCGImage:imageRef]; }
CGImageRelease(imageRef); CGContextRelease(context); }
CGColorSpaceRelease(colorSpaceRef); CGImageRelease(iref); CGDataProviderRelease(provider);
if(pixels) { free(pixels); } return image; } //Конец функции по конвертации массива в изображение
В результате вышеуказанной реализации, устанавливается в imageView белый экран.
Вопрос: Как изменить реализацию так, чтобы в imageView был заполнен разноцветными точками (чем-нибудь отличающимся от белого цвета)?


Ответ

Вот этот код генерирует мне картинку шума, если его вставить, например, во viewDidLoad
int width = 500; int height = 500;
size_t bufferLength = width * height * 4; uint8_t* pixels = (uint8_t*)malloc(bufferLength); for (int i = 0; i < bufferLength; i++) { pixels[i] = rand() % 255; }
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(pixels, width, height, 8, width * 4, space, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast);
CGImageRef toCGImage = CGBitmapContextCreateImage(ctx); UIImage * uiimage = [[UIImage alloc] initWithCGImage:toCGImage];
CGImageRelease(toCGImage); CGColorSpaceRelease(space); CGContextRelease(ctx); free(pixels); UIImageView *imageView = [[UIImageView alloc] initWithImage:uiimage]; [self.view addSubview:imageView];
Для заполнения массива чем-то конкретным
Есть формат пикселя, который определяется параметром kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast. Это значит RGBA, то есть каждый пиксель состоит из 4-х байтов, последовательно - красный (Red), зелёный (Green), синий (Blue), альфа (прозрачность). То есть, для установки конкретного массива пикселей, нужно забивать массив последовательностью из 4-х байт, последний из которых - 255 (то есть без прозрачности). Например:
for (int i = 0; i < width * height; i++) { pixels[i * 4] = 100; //баланс красного pixels[i * 4 + 1] = 200; //баланс зеленого pixels[i * 4 + 2] = 50; //баланс синего pixels[i * 4 +3] = 255; //прозрачности }

понедельник, 26 ноября 2018 г.

Ускорить загрузку сайта

Здравствуйте. Как лучше организовать хранение фотографий?
Как лучше сохранять изображения от пользователей (аватар, обложка страницы, посты на стене и т.д.). В скольких размерах? Например, миниатюра 60х60, основное фото профиля 200х200, увеличенная версия - 1000х1000. Так? И как тогда это оптимизировать? В скрипте если будет три фото сразу сохраняться, не слишком ли долго будет это происходить?


Ответ

Если это каталог, то можно организовать lazy load. Плагин на jquery
Второй вариант http-кэширование. Детальнее по нему (так же рекомендую почитать).
Ну и делать тумбы. А разрешения вы сами подбираете под свой проект.

вторник, 2 октября 2018 г.

C# и нейронные сети. С чего начать и в какую сторону смотреть?

Вопрос довольно общий, знаю.
Но я здесь немного уточню что бы было не так расплывчасто.
Интересует общая сжатая теория. С какой статьи лучше начать? Интересуют актуальные библиотеки C# Интересует приблизительная реализация уже созданной в нескольких вариациях идеи -- скармливаешь нейронке много изображений-пар: большое и маленькое. А нейронка учится делать из маленького большое и потом сравнивает сделанное большое и то большое которое ему скормили что бы понять что сделано не так. Какую нейронку лучше выбрать под даную задачу? Не слишком ли сложная и на сколько вообще реальная задачка в 3, если учесть что я вообще ни бум-бум в нейронных сетях? Если задача непосильная для новичка в НС, то с каких задач-тренировок лучше начинать?


Ответ

Одна из самых изысканных задач для НС приведена в этой статье, можно понять уровень проблематики и алгоритмов, которые задействуются для решений подобного класса задач и где действительно нужна НС. Примеры на OpenCV, что тоже замечательно.
OpenCV - Библиотека с самой открытой лицензией и исходным кодом, написана на C++. Под C# есть wrapper'ы - EmguCV, OpenCV for Unity (можно и без Unity использовать). Есть адаптация для Visual Studio (C++), Objective C, Android Studio, Python.
Даже для умеренно сложных задач НС обычно не нужна, и не очень даже применима - часто приходится делать обработку видеопотока в реальном времени, а НС не самая быстрая штука далеко. По этой и еще ряду причин большинство разработчиков, уверенных поначалу что им нужна НС, от этой идеи впоследствии отказываются. Благо в OpenCV реализовано огромное количество алгоритмов на все случаи жизни - почти всё, что связано с обработкой видео и изображений там есть.
После редактирования автором вопроса редактирую ответ :-)
Большинство алгоритмов, реализованных в доступных пакетах, в основном предназначены для down-scaling, спрос на это очевиден - камера снимает в большом разрешении, а в Интернеты лучше постить, предварительно уменьшив фотку - этим пользуются все активные пользователи Интернетов и соцсетей.
Up-scaling задача тоже достаточно хорошо проработана, просто спрос на нее несоизмеримо меньше - тем не менее любой дизайнер отлично знает, что нужно делать, чтобы изображение можно было без проблем увеличивать - взять Corel Draw или другой пакет векторной графики, то есть сделать изображение векторным.
Таким образом, если маленькое растровое изображение преобразовать в векторы, сделать up-scaling, мы скорее всего уже получим что-то интересное - обратите внимание на программу Potrace. В OpenCV готового для raster->vector ничего нет. Хотя из доступных инструментов и можно слепить что-то, врядли получится лучше чем у Potrace - всё-таки там люди занимались этой проблемой специально. Potrace идёт с исходниками и подробным описанием алгоритмов, так что простор для творчества полный :-)
И самое интересное на десерт - пора взглянуть на ваше увеличенное изображение, и путем сравнения с полученным в результате векторизации и up-scaling результатом выявить отклонения. Выявленные отклонения могут являться материалом для обучения НС. Например, можно пойти путем векторизации большого изображения, выявления соответствия кривых и сравнения их характеристик. По результатам обучения НС начнет выдавать некие рекомендации по коррекции кривых в произвольных изображениях. Может быть даже замахнуться на добавление кривых, типа дополнительных цветовых контуров градиента (хотя градиент в полученном изображении проще будет сгладить с помощью функций Blur и т.п.)