Имя: Пароль:
1C
1С v8
Работа с картинкой: нужно по пикселям разобрать картинку в формате jpeg или jpg
0 katerinaUniv
 
11.01.20
04:55
Имеется некоторый набор файлов jpg, размером 70*200. Мне нужно разобрать данные файлы по пикселям, чтобы исправить/проанализировать изображение. Результат разбора хочу поместить в таблицу значений 70*200, где в каждой ячейке таблицы будет цвет. Далее упрощаю до двухцветного изображения, и анализирую, что нарисовано. То есть есть определенный символ или нет. Пока проблема в том, что получаю двоичные данные картинки, но не могу понять, как пройтись циклом по каждому пикселю и получить его положение и цвет. Может кто-нибудь знает ответ?
1 ДенисЧ
 
11.01.20
05:17
Взять внешнюю компоненту какую-нибудь. Зачем всё это тащить в 1с?
2 katerinaUniv
 
11.01.20
05:24
Через какую например? Мне изображение нужно разбить в матрицу пикселей с цветами (таблица значений), обработать (упростить) и отрисовать на элементе формы
3 katerinaUniv
 
11.01.20
05:24
Задача: распознавать наличие определенных символов на изображениях и в зависимости от результата распознавания выполнять действия
4 Turku
 
11.01.20
05:30
Гуглите по запросу: 1С OCR.
Например, http://catalog.mista.ru/public/586313/
5 ДенисЧ
 
11.01.20
05:30
Ну блин... Всё через одно место...
Формат файлов известен, бинарные потоки в 1с есть. Так что открывай спецификацию и вперёд...
6 katerinaUniv
 
11.01.20
05:30
Тут в зависимости от того, какие изображения будут давать, возможно придется угадывать функцию линии, наклон, кривизну
7 katerinaUniv
 
11.01.20
05:31
(5)я получила двоичные данные, в исходниках-примерах, которые я нагуглила, получают ширину/высоту файла. А вот как разобрать двоичные данные по пикселям мне не понятно
8 katerinaUniv
 
11.01.20
06:00
(4) у меня не совсем такое распознавание, поэтому в идеале свою нейросеть. А я не то, что до нее, я не могу даже до чтения картинки дойти...
9 DES
 
11.01.20
06:09
А в бинарном файле можете получить 21 байт?
10 ДенисЧ
 
11.01.20
06:26
(9) Я получал...
11 katerinaUniv
 
11.01.20
06:29
Мне нужен алгоритм прохода циклом по пикселям и получения цвета каждого пикселя в картинке в формате png или jpeg. Читаю про форматы, но никак не пойму, как с двоичных данных вытащить цвета.
12 trdm
 
11.01.20
06:30
(11) заказывай на фрилансе.
13 DES
 
11.01.20
06:32
Там нет пикселей пока,
нам есть сжатый архив.
Типа как RAR АРХИВ, там нет файлов в том виде в котором вам привычно,
14 katerinaUniv
 
11.01.20
06:34
(13)это я начала понимать, что часть файла после заголовка некоторый ключ, часть файла - сами данные, с шифром ключа
15 katerinaUniv
 
11.01.20
06:35
Я смотрела компоненты, но там только растянуть/повернуть, добавить лого. Кому-нибудь попадались компоненты по переданным координатам пикселя получить цвет?
16 DES
 
11.01.20
06:41
17 DES
 
11.01.20
06:54
JPEGfix позволяет:
1) Просматривать фотографии и прочие изображения в формате JPEG, даже если они повреждены, включая потерю заголовка
2) Вносить поправки в изображение, восстанавливающие искажение цвета и сдвиг
3) Сохранять изображение в формате JPEG или BMP
4) Экспортировать изображение в растре YCbCr или в DCT-коэффициентах для обработки в других программах
5) Также в программу включены различные средства анализа файлов и повреждений


вот 4 пункт можно заюзать.
18 trdm
 
11.01.20
06:55
(14) можно написать консольку, которая распакует картинку в нужный формат. или перевести в bmp - там структура проще, но и вес больше.
19 trdm
 
11.01.20
06:57
(17) спасибо.
20 katerinaUniv
 
11.01.20
08:36
(14) вот пробую. Смущает, что при чтении biPlanes получается на 1, а 256 и biBitCount 6144
21 katerinaUniv
 
11.01.20
08:36
Какие-то нереальные значения
22 katerinaUniv
 
11.01.20
08:37
//пробую текущую картинку преобразовать в BMP и прочитать его структуру
    Картинка = Новый Картинка(ПутьКФайлу);
    Картинка = Картинка.Преобразовать(ФорматКартинки.PNG);
    КартинкаБМП = Картинка.Преобразовать(ФорматКартинки.BMP);
    ДанныеКартинки = КартинкаБМП.ПолучитьДвоичныеДанные();
    Поток = ДанныеКартинки.ОткрытьПотокДляЧтения();
    Чтение = Новый ЧтениеДанных(ДанныеКартинки,,ПорядокБайтов.BigEndian);
    bfType = Чтение.ПрочитатьЦелое16(ПорядокБайтов.BigEndian); //bfType
    bfSize = Чтение.ПрочитатьЦелое32();
    bfReserved1 = Чтение.ПрочитатьЦелое16();
    bfReserved2 = Чтение.ПрочитатьЦелое16();
    bfOffBits = Чтение.ПрочитатьЦелое32();
    ////BITMAPINFOHEADER // версия 3
    biSize = Чтение.ПрочитатьЦелое32();
    biWidth = Чтение.ПрочитатьЦелое32(); // ширина изображения в пикселах
    biHeight = Чтение.ПрочитатьЦелое32(); // высота изображения в пикселах
    biPlanes = Чтение.ПрочитатьЦелое16(); // содержит единицу
    biBitCount = Чтение.ПрочитатьЦелое16(); // количество бит на пиксел
    biCompression = Чтение.ПрочитатьЦелое32(); // тип сжатия
    biSizeImage = Чтение.ПрочитатьЦелое32(); // размер изображения в байтах
    biXPelsPerMeter = Чтение.ПрочитатьЦелое32(); // горизонтальное разрешение в пикселах на метр
    biYPelsPerMeter = Чтение.ПрочитатьЦелое32(); // вертикальное разрешение в пикселах на метр
    biClrUsed = Чтение.ПрочитатьЦелое32(); //  количество используемых цветовых индексов в палитре
    biClrImportant = Чтение.ПрочитатьЦелое32(); // количество индексов

    //мКартинки = Новый Массив(biHeight,biWidth);
    мКартинки = Новый Массив(10000,10000);
    Для а1 = 0 По biHeight-1 Цикл
        Для а2 = 0 По biWidth - 1 Цикл
            блю = Чтение.ПрочитатьБайт();
            грин = Чтение.ПрочитатьБайт();
            ред = Чтение.ПрочитатьБайт();
            цвет = Новый Цвет(ред,грин,блю);
            мКартинки[а1][а2] = цвет;
        КонецЦикла;
    КонецЦикла;
23 katerinaUniv
 
11.01.20
08:38
Высота получается 1 174 405 120, ширина 3 355 443 200. А читает картинку вроде правильно, там угол белый, потом сереет.
24 katerinaUniv
 
11.01.20
08:39
Массив такого объема не создается, значит файл надо упростить по параметрам biPlanes и biBitCount, теперь нужна помощь в этом...
25 katerinaUniv
 
11.01.20
08:39
Либо не так просто читаю
26 Cyberhawk
 
11.01.20
08:58
А что, из Зазеркалья уже статейку-то позабыли?
27 katerinaUniv
 
11.01.20
09:10
(26) откуда?
28 NorthWind
 
11.01.20
09:53
вы на полном серьезе хотите подобные вещи в 1С делать? Ну вы блин даете...
29 Cyberhawk
 
11.01.20
09:55
(27) https://wonderland.v8.1c.ru/
Хотя посмотрел ту статью - там пробегаются по пикселам из предположения что они уже получены)
30 NorthWind
 
11.01.20
10:10
Высота получается 1 174 405 120, ширина 3 355 443 200 -- что-то многовато, нет?
И насчет BigEndian по умолчанию вы уверены? Так-то у процов intel и на платформе Windows преимущественно Little Endian порядок байтов...
31 NorthWind
 
11.01.20
10:15
32 Генератор
 
11.01.20
10:22
Порядок байт в 16-битных и 32-битных ячейках повсюду от младшего к старшему (little-endian)

https://ru.wikipedia.org/wiki/BMP#Внутреннее_строение
33 Garykom
 
гуру
11.01.20
10:40
(0) Если файлов картинок много то только внешние средства, некую ВК или прогу, кодом на 1С на надо будет тормозно.
34 Asmody
 
11.01.20
12:54
Может фигнёй не заниматься, а взять правильный инструмент?
Для распознавания картинок пацаны рекомендуют python и ImageAI. Говорят, в 10 строк что хошь распознаёт.
35 Злопчинский
 
11.01.20
13:02
GFLax
36 NorthWind
 
11.01.20
13:40
(33) думаю, не просто тормозно, а очень тормозно. Заниматься математикой на таких матрицах, какие дают картинки современных мегапиксельных размеров, можно только в машинных кодах. А для этого надо иметь нормальные библиотеки, как в питоне, или самому писать математику хотя бы на С/С++, который компилируется в приличный машинный код. Ну, может быть, на свежих машинах еще Java/C# сгодятся. Но не 1С уж точно.
37 katerinaUniv
 
11.01.20
14:49
(28) пока ни одна компонента не возвращает мне картинку по цветам пикселей... пытаюсь сделать сама
38 wt
 
11.01.20
16:23
Похоже ТС занимается построением траектории обнаружения?
39 Garykom
 
гуру
11.01.20
16:38
40 Garykom
 
гуру
11.01.20
16:46
Лично так как я нынче Golang осваиваю то взял бы https://socketloop.com/tutorials/golang-get-rgba-values-of-each-image-pixel и завернул в простейший exe, который при запуске поднимает http сервис на указанном порту.
И можно через HTTPСоединение отправить jpeg в ответ получив в json массив RGB точек.
41 Мэс33
 
11.01.20
16:46
На питоне есть масса решений для распознавания картинок.
42 Garykom
 
гуру
11.01.20
16:47
(41) Они на чем угодно есть.
На питоне можно сделать (и как сложно) нечто что банальным образом используется из 1С?
43 Garykom
 
гуру
11.01.20
16:48
(40)+ Мне подобный сервис писать примерно час, может два.
44 Мэс33
 
11.01.20
16:48
(42) на чем угодно !== Легко использовать
Питон все же понятнее, легче, приятнее
45 Garykom
 
гуру
11.01.20
16:49
(44) И как использовать это на питоне без установки питона, апача и прочих?
46 Garykom
 
гуру
11.01.20
16:49
(45)+ Плюс C# и Go в том что можно в exe (или в dll) скомпилить и это штатная фича.
47 Garykom
 
гуру
11.01.20
16:50
Хмм сча
48 Мэс33
 
11.01.20
16:50
(45) апач зачем? Тут как я понял есть набор картинок, наверное на диске.
49 Мэс33
 
11.01.20
16:53
(46) из 1с можно вызвать батник, а он уже стартанет все что угодно
50 Garykom
 
гуру
11.01.20
16:55
(47)+ https://i.paste.pics/dbe164449241c5aaefbf6db7023b3a92.png

Код на Го из (40) работает отлично, банально вместо консоли писать в текстовый файл, а на 1С сначала exe запускаем с ключами строки указывая каталог или имя файла jpg а затем читаем полученные csv
51 Garykom
 
гуру
11.01.20
16:56
(49) Питон где взять? Тут банальный exe который даже можно в макет встроить.

Я пока не допилил свою хрень чтобы ВК для 1С нормально было делать, дальше тестового но работающего примера не зашел.
52 Garykom
 
гуру
11.01.20
16:56
(51) *чтобы ВК для 1С на Golang нормально было делать
53 Мэс33
 
11.01.20
16:57
(51) где взять питон. Какой сложный вопрос.
Кстати, питон можно тоже в exeшник собрать
54 Garykom
 
гуру
11.01.20
16:58
(53) Ок покажи пример на питоне, хотя бы как у меня на Go :)
55 Garykom
 
гуру
11.01.20
16:59
(54)+ У меня ушло 5 минут, за 10-20 минут я добавлю ключи запуска или перебор файлов в каталоге и запись в csv и считай готово
56 fisher
 
11.01.20
17:06
(0) Короче суть в том, что самой парсить исходный формат изображения - дело неблагодарное. Там везде свои хитрые приколы хранения информации о цвете. Нужно задействовать готовую либу или утилиту, которая уже умеет раскладывать пиксели с их цветами во вменяемый для дальнейшей обработки формат.
57 fisher
 
11.01.20
17:09
Хотя погоди. Каким именно образом ты собираешься "упростить до двухцветного изображения"? До монохрома, имелось в виду? Это же можно делать по-разному с разным результатом на выходе. И для этого тоже можно использовать готовые инструменты.
58 Мэс33
 
11.01.20
17:23
(55) молодец. Ты победил.
ТС, юзай это решение
59 Garykom
 
гуру
11.01.20
17:42
Решение с конверталкой из jpeg в csv на Golang:

package main

import (
    "encoding/csv"
    "fmt"
    "image"
    "image/jpeg"
    "os"
    "strconv"
)

func init() {
    // damn important or else At(), Bounds() functions will
    // caused memory pointer error!!
    image.RegisterFormat("jpeg", "jpeg", jpeg.Decode, jpeg.DecodeConfig)
}

func StrXYRGBA(x, y int, r, g, b, a uint32) []string {
    result := make([]string, 6)

    result[0] = strconv.Itoa(x)
    result[1] = strconv.Itoa(y)
    result[2] = strconv.Itoa(int(r))
    result[3] = strconv.Itoa(int(g))
    result[4] = strconv.Itoa(int(b))
    result[5] = strconv.Itoa(int(a))

    return result
}

func main() {

    args := os.Args
    if len(args) < 3 {
        fmt.Println("Missing image and result csv filename!")
        os.Exit(1)
    }

    imageFilename := args[1]
    resultFilename := args[2]
    fmt.Println("Convert from " + imageFilename + " to " + resultFilename)

    imgfile, err := os.Open(imageFilename)

    if err != nil {
        fmt.Println("img.jpg file not found!")
        os.Exit(1)
    }

    defer imgfile.Close()

    // get image height and width with image/jpeg
    // change accordinly if file is png or gif

    imgCfg, _, err := image.DecodeConfig(imgfile)

    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    width := imgCfg.Width
    height := imgCfg.Height

    fmt.Println("Width : ", width)
    fmt.Println("Height : ", height)

    // we need to reset the io.Reader again for image.Decode() function below to work
    // otherwise we will  - panic: runtime error: invalid memory address or nil pointer dereference
    // there is no build in rewind for io.Reader, use Seek(0,0)
    imgfile.Seek(0, 0)

    // get the image
    img, _, err := image.Decode(imgfile)

    fmt.Println(img.At(10, 10).RGBA())

    data := [][]string{}

    for y := 0; y < height; y++ {
        for x := 0; x < width; x++ {
            r, g, b, a := img.At(x, y).RGBA()
            //fmt.Printf("[X : %d Y : %v] R : %v, G : %v, B : %v, A : %v  \n", x, y, r, g, b, a)
            row := StrXYRGBA(x, y, r, g, b, a)
            data = append(data, row)
        }
    }

    csvfile, err := os.Create(resultFilename)

    if err != nil {
        fmt.Println(err)
    }

    csvwriter := csv.NewWriter(csvfile)
    csvwriter.UseCRLF = true

    for _, row := range data {
        _ = csvwriter.Write(row)
    }

    csvwriter.Flush()

    csvfile.Close()
}
60 Garykom
 
гуру
11.01.20
17:45
(59) Запускать банально
jpeg.exe D:\Work\go\jpeg\img.jpg D:\Work\go\jpeg\img.csv
61 Генератор
 
11.01.20
17:45
автор в (8) пишет про нейросеть, наверное бессмысленно это в 1с грузить, в 1с надо уже готовый результат
62 Garykom
 
гуру
11.01.20
17:50
(34) Прикольная штука этот ImageAI да
63 Мэс33
 
11.01.20
19:33
(59) а дальше распознавать чем, одинэсиной?
64 Garykom
 
гуру
11.01.20
19:48
(63) ТС дальше не спрашивала, перевести в серое или черно-белое тоже не проблема а вот что дальше хз.
65 Мэс33
 
11.01.20
19:57
(64) видишь ли, с опытом учишься уже телепатии. ТС решает проблему не с того конца не тем инструментом. В конечном итоге тс хочет распознать символы. Для этого есть готовые либы, самые простые в использовании (настройка, обучение) - либы на питоне. Перегнать в массив - это ерунда, ты показал на go - и это круто. Главное ведь не это, а - что делать с этим массивом.
66 Кирпич
 
11.01.20
20:40
Человек заморачивается такими задачами и не знает ни одного языка программирования. Странно.
67 25-11
 
11.01.20
20:51
Можно экспериментировать с передачей изображения Гуглу для распознавания текста. Из 1С вызывается легко,
см. http://catalog.mista.ru/public/586313/
68 Мэс33
 
11.01.20
20:57
(67) бесплатно?
69 Мэс33
 
11.01.20
22:53
(67) а если у тс в картинках не текст? А образы какие нибудь?
70 NorthWind
 
11.01.20
23:03
ТС уж сбежала давно :)
71 Мэс33
 
12.01.20
11:06
(70) стало стыдно
72 NorthWind
 
12.01.20
15:14
(71) мне вот более интересно - ну ладно, есть у тебя матрица, хорошо. Но вычленить оттуда картинку с учетом всех неточностей и сравнить ее с каким-то паттерном, определив степень схожести выше некоего порога - это же сама по себе достаточно серьезная задачка, по сравнению с которой получение матрицы из джипега вообще ни о чем. Люди нейронные сети юзают для этого. Неужто чел на полном серьезе собрался это в 1С делать? :-O
73 Garykom
 
гуру
12.01.20
15:32
(72) Подготовка и очистка данных это 80-90%% в ML.
Далее готовые "алгоритмы".
74 NorthWind
 
12.01.20
15:47
(73) это ежу понятно. Вопрос - накой матрица в 1С, если библиотек ML там нет?
75 NorthWind
 
12.01.20
15:49
вопрос из серии "ну допустим пробил ты головой стену, и что ты будешь делать в соседней камере?" :))
76 katerinaUniv
 
13.01.20
11:15
Спасибо всем за помощь. Вот рабочий код:

Картинка = Новый Картинка(ПутьКФайлу);
    //Картинка.
    Картинка = Картинка.Преобразовать(ФорматКартинки.PNG);
    КартинкаБМП = Картинка.Преобразовать(ФорматКартинки.BMP);
    
    ДанныеКартинки = КартинкаБМП.ПолучитьДвоичныеДанные();
    Поток = ДанныеКартинки.ОткрытьПотокДляЧтения();
    Чтение = Новый ЧтениеДанных(ДанныеКартинки);//,,ПорядокБайтов.BigEndian);
    bfType = Чтение.ПрочитатьЦелое16();//ПорядокБайтов.BigEndian); //bfType
    bfSize = Чтение.ПрочитатьЦелое32();
    bfReserved1 = Чтение.ПрочитатьЦелое16();
    bfReserved2 = Чтение.ПрочитатьЦелое16();
    bfOffBits = Чтение.ПрочитатьЦелое32();
    ////BITMAPINFOHEADER // версия 3
    biSize = Чтение.ПрочитатьЦелое32();
    biWidth = Чтение.ПрочитатьЦелое32(); // ширина изображения в пикселах
    biHeight = Чтение.ПрочитатьЦелое32(); // высота изображения в пикселах
    biPlanes = Чтение.ПрочитатьЦелое16(); // содержит единицу
    biBitCount = Чтение.ПрочитатьЦелое16(); // количество бит на пиксел
    biCompression = Чтение.ПрочитатьЦелое32(); // тип сжатия
    biSizeImage = Чтение.ПрочитатьЦелое32(); // размер изображения в байтах
    biXPelsPerMeter = Чтение.ПрочитатьЦелое32(); // горизонтальное разрешение в пикселах на метр
    biYPelsPerMeter = Чтение.ПрочитатьЦелое32(); // вертикальное разрешение в пикселах на метр
    biClrUsed = Чтение.ПрочитатьЦелое32(); //  количество используемых цветовых индексов в палитре
    biClrImportant = Чтение.ПрочитатьЦелое32(); // количество индексов

    мКартинки = Новый Массив(biHeight,biWidth);
    //мКартинки = Новый Массив(10000,10000);
    Для а1 = 0 По biHeight-1 Цикл
        Если а1 = 9999 Тогда Прервать; КонецЕсли;
        Для а2 = 0 По biWidth - 1 Цикл
            Если а2 = 9999 Тогда Прервать; КонецЕсли;
            блю = Чтение.ПрочитатьБайт();//ПрочитатьВБуферДвоичныхДанных(8);//.ПрочитатьБайт();
            грин = Чтение.ПрочитатьБайт();
            ред = Чтение.ПрочитатьБайт();
            цвет = Новый Цвет(ред,грин,блю);
            мКартинки[а1][а2] = цвет;
        КонецЦикла;
    КонецЦикла;
77 katerinaUniv
 
13.01.20
11:19
Помог совет (31), а дальше извините, пропала на время
Дело в том, что в тех библиотеках, которые тут советовали, распознаются ровные символы насколько я поняла. В общем ни одна библиотека не распознает то, что мне нужно. А задача интересная. Если уж не решу, то как минимум узнаю много нового :). Да, буду пробовать сделать нейронную сеть по типу нейронного перцептрона (сейчас вспоминаю как это было в институте). Еще на лабораторной оно все работало в vb. Другие языки знала на этапе обучения в институте, в основном писала на C#, но за годы работы навыки растерялись. Поэтому пробую сначала на 1С. Будут тормоза - придется сделать свою библиотеку.
78 pechkin
 
13.01.20
11:23
нейронка, которая на датасете из 1000 картинок будет обучаться 1 год )))
79 NorthWind
 
13.01.20
20:11
(77) у вас очень небольшая картинка, я как-то упустил этот момент. Если изображение не планируется увеличивать, то может и взлететь. А вот если могут быть больше - тогда, думаю, 1С не вариант.