Re: Чем заменить NumPy операции на массивах в C++ и JS
От: paradok  
Дата: 20.10.23 06:58
Оценка: 2 (1) +1
Здравствуйте, Артём, Вы писали:

https://www.codeconvert.ai/python-to-c++-converter

#include <iostream>
#include <opencv2/opencv.hpp>

int main() {
float scale = 1.0 / 255.0;
cv::Size shape(1, 1, 3);
cv::Mat mean = (cv::Mat_<float>(3, 1) << 0.485, 0.456, 0.406);
cv::Mat std = (cv::Mat_<float>(3, 1) << 0.229, 0.224, 0.225);

CV_Assert(img.type() == CV_32F);
cv::Mat normalizedImg = (img * scale — mean) / std;

return 0;
}
Чем заменить NumPy операции на массивах в C++ и JS
От: Артём Австралия жж
Дата: 19.10.23 21:30
Оценка:
Портирую скрипт, там одной строчкой 3 мерный массив (картинка с триплетами) умножается на скаляр, отнимается вектор-триплет и умножается на вектор-триплет — с помощью numpy.
Туплю, как эту операцию в одну строку заменить одной строкой numjs. Ладно JS, но в C++ кто-то ж портирует наверное. Как нужно матчить c Python numpy в C++ например?

scale = np.float32(1.0 / 255.0)  # scalar
shape = (3, 1, 1)
mean = np.array([0.485, 0.456, 0.406]).reshape(shape).astype('float32')  # vector (3dim array)
std = np.array([0.229, 0.224, 0.225]).reshape(shape).astype('float32')  # vector (3dim array)

assert isinstance(img,
                          np.ndarray), "invalid input 'img' in NormalizeImage"

img = img.astype('float32') * scale - mean) / std   # <=== Как ЭТО портируют в C++ или JS?
Отредактировано 19.10.2023 21:46 Артём . Предыдущая версия . Еще …
Отредактировано 19.10.2023 21:31 Артём . Предыдущая версия .
Re: Чем заменить NumPy операции на массивах в C++ и JS
От: reversecode google
Дата: 19.10.23 23:30
Оценка:
совсем по простому ответ — НИКАК
когда мне предожии несколько лет назад перевести одну ML хрень с питона на С++
я изрыл весь интернет и ничего не нашел адекватнго
ответил заказчику что мне нужен ресерч + денег что бы я написал некий аналог numpy, заказчик отказался
буквально несколько месяцев назад наткнулся на одну статью кажеться на хабре
где чел начал это делать сам just for fun
https://github.com/mgorshkov/
полистайте там несколько либ
есть и некий np типа замена numpy
и есть другие не помню у него проекты, внутри кторых есть функционал для замены numpy
Re: Чем заменить NumPy операции на массивах в C++ и JS
От: Vzhyk2  
Дата: 20.10.23 10:03
Оценка:
Здравствуйте, Артём, Вы писали:

Аё>но в C++ кто-то ж портирует наверное. Как нужно матчить c Python numpy в C++ например?

Я бы посоветовал ручками на Eigen (если тензоры есть) или на armadillo (если только матрицы). При правильной инсталляции и настройке эти либы могут юзать оптимизированные MKL, ATLAS и т.п.
Re[2]: Чем заменить NumPy операции на массивах в C++ и JS
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 20.10.23 10:21
Оценка:
Здравствуйте, Vzhyk2, Вы писали:

V>Я бы посоветовал ручками на Eigen (если тензоры есть) или на armadillo (если только матрицы). При правильной инсталляции и настройке эти либы могут юзать оптимизированные MKL, ATLAS и т.п.


Странный выбор, на первый взгляд. Чем они быстрее для картинок, чем OpenCV? Который, в свою очередь, может использовать и IPP, и OpenCL, и минимальными усилиями CUDA.
Re[2]: Чем заменить NumPy операции на массивах в C++ и JS
От: Артём Австралия жж
Дата: 20.10.23 20:35
Оценка:
Здравствуйте, paradok, Вы писали:

P>https://www.codeconvert.ai/python-to-c++-converter


P>#include <iostream>

P>#include <opencv2/opencv.hpp>

P>int main() {

P> float scale = 1.0 / 255.0;
P> cv::Size shape(1, 1, 3);
P> cv::Mat mean = (cv::Mat_<float>(3, 1) << 0.485, 0.456, 0.406);
P> cv::Mat std = (cv::Mat_<float>(3, 1) << 0.229, 0.224, 0.225);

P> CV_Assert(img.type() == CV_32F);

P> cv::Mat normalizedImg = (img * scale — mean) / std;

P> return 0;

P>}

Спасибо за подсказку. Попытался это повторить на TS/JS — ничего не вышло . Конвертор из питона в ts и в js наконвертил тоже некомпилируемый код . Остался на медленном переборе пока что.
import * as nj from 'numjs';
declare var cv;
//...


const imageRGB = new cv.Mat();
cv.cvtColor(image, imageRGB, cv.COLOR_BGRA2RGB, 3);

const img = nj.array(imageRGB.data, 'float32').reshape(imageRGB.rows, imageRGB.cols, imageRGB.channels());

const [h, w, c] = img.shape;
// numpy: (img.astype('float32') * self.scale - self.mean) / self.std
for (let y = 0; y < h; ++y) {
  for (let x = 0; x < w; ++x) {
    for (let i = 0; i < c; ++i) {
      const originalUint8 = img.get(y, x, i);
      const normalisedFloat32 = (originalUint8 * this.scale - this.mean[i]) / this.std[i];
      img.set(y, x, i, normalisedFloat32);
    }
  }
}

return img;


Оба OpenCV и NumJS бросают на попытке операции на 2 массивах с разной shape. Возможно, NumPy под капотом размножает 1 пиксел (вектор) на всю shape чтоб совпадали размеры- хз.

Попробовать тоже для исходной картинки сделать такого же размера 2 маски одна mean, вторая std и тогда скормить в OpenCV?
Отредактировано 22.10.2023 3:34 Артём . Предыдущая версия .
Re[3]: OpenCV.js смог - если кому интересно
От: Артём Австралия жж
Дата: 22.10.23 06:48
Оценка:
Здравствуйте, Артём, Вы писали:

Аё>Оба OpenCV и NumJS бросают на попытке операции на 2 массивах с разной shape. Возможно, NumPy под капотом размножает 1 пиксел (вектор) на всю shape чтоб совпадали размеры- хз.


Аё>Попробовать тоже для исходной картинки сделать такого же размера 2 маски одна mean, вторая std и тогда скормить в OpenCV?


    // numpy: (img.astype('float32') * self.scale - self.mean) / self.std

    const imageRGB32F = new cv.Mat();
    const imageRGB = new cv.Mat();
    cv.cvtColor(image, imageRGB, cv.COLOR_BGRA2RGB, 3);

    imageRGB.convertTo(imageRGB32F, cv.CV_32F, this.scale);
    cv.subtract(imageRGB32F,
      new cv.Mat(image.rows, image.cols, cv.CV_32FC3, [...this.mean, 1]),
      imageRGB32F);
    cv.divide(imageRGB32F,
      new cv.Mat(image.rows, image.cols, cv.CV_32FC3, [...this.std, 1]),
      imageRGB32F);

    data.image = nj.array(imageRGB32F.data32F, 'float32').reshape(...matImageShape(imageRGB32F));


\* всe Mat должны удаляться вручную после использования imageRGB.delete(). Мемоизация и авто-удаление за кадром.

PPS всё заработало, всё удалось- сначала как NodeJS, затем в браузере на планшетах и смартфонах в SPA приложении фича SOTA computer vision крутит модели PaddleOCR на движке ONNX Runtime на девайсе.

Спасибо Nuzhny за наводки на этом форуме!
Отредактировано 04.11.2023 1:33 Артём . Предыдущая версия . Еще …
Отредактировано 22.10.2023 6:49 Артём . Предыдущая версия .
Re[3]: Чем заменить NumPy операции на массивах в C++ и JS
От: Vzhyk2  
Дата: 24.10.23 10:08
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Странный выбор, на первый взгляд. Чем они быстрее для картинок, чем OpenCV? Который, в свою очередь, может использовать и IPP, и OpenCL, и минимальными усилиями CUDA.

Это был всего-лишь совет, а не жесткое требование. Нравится см::mat, юзай. Мне OpenCV не нравится, но в ней есть реализации некоторых алгоритмов, которых больше нигде нет, хотя часто реализации медленные и кривенькие.
Eigen вообще на тензоры задаточен и удобен и умеет юзать оптимизированные либы от того же интела, armadillo только на матрицы и для меня очень удобна в использовании и в общем нормально подхватывает оптимизированные либы.
А cv::mat — мне сильно не удобна и странная для меня, как программиста пользователя ее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.