【HarmonyOS 7新能力|079】3DGS性能验证:设计可复现的指标与测试清单
2026/10/4 15:30:59
原图:
调用dot和convolution后的图像:
位图图像前54byte为文件头,其后为像素信息,定义xyz函数访问(x,y)处的第z个颜色分量
byte_t& Image::xyz(int64_t x, int64_t y, int64_t z) { x = lader(x, (int64_t)0, (int64_t)this->bih.width - 1); y = lader(y, (int64_t)0, (int64_t)this->bih.height - 1); return this->bitmap[y * this->row_size + x * 3 + z]; }Image.h头文件包含图像文件读取和修改
#pragma once #include <iostream> #include <fstream> #include <utility> #include <cmath> typedef unsigned char byte_t; typedef unsigned short word_t; const double pi = acos(-1); template <typename T> struct Point { T x; T y; Point(T _x, T _y) : x{ _x }, y{ _y } {} Point<T>& operator += (Point<T> p) { this->x += p.x; this->y += p.y; return *this; } Point<T>& operator -= (Point<T> p) { this->x -= p.x; this->y -= p.y; return *this; } Point<T>& operator *= (Point<T> p) { this->x *= p.x; this->y *= p.y; return *this; } Point<T>& operator /= (Point<T> p) { this->x /= p.x; this->y /= p.y; return *this; } Point<T> operator + (Point<T> p) { return Point<T>(this->x + p.x, this->y + p.y); } Point<T> operator - (Point<T> p) { return Point<T>(this->x - p.x, this->y - p.y); } Point<T> operator * (Point<T> p) { return Point<T>(this->x * p.x, this->y * p.y); } Point<T> operator / (Point<T> p) { return Point<T>(this->x / p.x, this->y / p.y); } Point<T> operator + (T t) { return Point<T>(this->x + t, this->y + t); } Point<T> operator - (T t) { return Point<T>(this->x - t, this->y - t); } Point<T> operator * (T t) { return Point<T>(this->x * t, this->y * t); } Point<T> operator / (T t) { return Point<T>(this->x / t, this->y / t); } }; double fract(double _X) { return _X - floor(_X); } int64_t floor_int(double _X) { return (int64_t)floor(_X); } int64_t ceil_int(double _X) { return (int64_t)ceil(_X); } void pause(const char* text = "press any key to continue...\n") { std::cout << text; int ch = getchar(); } template <typename T> T lader(T t, T l, T r) { return t < l ? l : (t > r ? r : t); } double color_lader(double t) { return lader(t, 0.0, 255.0); } byte_t discretization(byte_t val, int num) { return byte_t(byte_t(val / 256.0 * num) * (255 / num)); } byte_t line(byte_t val, double k, double b) { return byte_t((val / 255.0 * k + b) * 255.0); } byte_t sin_2(byte_t val) { double t = sin(val / 512.0 * pi); t = t * t * 255.0; return byte_t(t); } byte_t sin_n(byte_t val, double num) { double t = sin(val / 512.0 * pi); t = pow(t, (double)num) * 255.0; return byte_t(t); } Point<double> rotate(Point<double> p, double theta) { double r = sqrt(p.x * p.x + p.y * p.y); return Point<double>(cos(r * theta) * p.x - sin(r * theta) * p.y, sin(r * theta) * p.x + cos(r * theta) * p.y); } Point<double> quadrilateral(Point<double> p, Point<double> p0, Point<double> p1, Point<double> p2, Point<double> p3) { p = (p + 1.0) * 0.5; return p0 * p.x * p.y + p1 * (1.0 - p.x) * p.y + p2 * (1.0 - p.x) * (1.0 - p.y) + p3 * p.x * (1.0 - p.y); } #pragma once #include "base.h" #pragma pack(push, 1) // BMP文件头结构体 struct BitmapFileHeader { uint16_t type; //BMP文件的类型,必须是 "BM" 才表示是BMP文件 uint32_t size; //文件大小(包括像素数据和所有头部信息) uint16_t reserved1; //保留字,必须设置为0 uint16_t reserved2; //保留字,必须设置为0 uint32_t offbits; //从文件开始到像素数据开始的字节偏移量 }; // BMP信息头结构体 struct BitmapInfoHeader { uint32_t size; //本结构体的大小 int32_t width; //图像的宽度(像素) int32_t height; //图像的高度(像素) uint16_t planes; //颜色平面数,必须设置为1 uint16_t bitcount; //每个像素的位数(1, 4, 8, 16, 24, 32) uint32_t compression; //使用的压缩类型 uint32_t sizeimage; //图像的大小(字节) int32_t xpels_per_meter; //水平分辨率(像素/米) int32_t ypels_per_meter; //垂直分辨率(像素/米) uint32_t color_used; //在位图中使用的颜色索引数 uint32_t color_important; //对图像显示有重要影响的颜色索引数 }; #pragma pack(pop) struct Image { byte_t* bitmap = nullptr; uint32_t row_size{}; BitmapFileHeader bfh{}; BitmapInfoHeader bih{}; Image() = default; ~Image() = default; errno_t open(const char* file); errno_t restore(const char* file); void free(); void header(Image& img); Image& operator = (Image& img); Image& operator = (Image&& img) noexcept; byte_t& xyz(int64_t x, int64_t y, int64_t z); }; errno_t Image::open(const char* file) { puts(file); std::ifstream in(file, std::ios::binary); if (in.fail()) return -1; in.read((char*)(&this->bfh), sizeof(BitmapFileHeader)); in.read((char*)(&this->bih), sizeof(BitmapInfoHeader)); in.seekg(this->bfh.offbits, std::ios::beg); this->bitmap = new byte_t[this->bih.sizeimage]; this->row_size = ((this->bih.width * 3 + 3) / 4) * 4; in.read((char*)(bitmap), bih.sizeimage); in.close(); std::cout << "Width: " << this->bih.width << std::endl; std::cout << "Heigth: " << this->bih.height << std::endl; return 0; } errno_t Image::restore(const char* file) { std::ofstream out(file, std::ios::binary); if (out.fail()) return -1; out.write((char*)(&this->bfh), sizeof(BitmapFileHeader)); out.write((char*)(&this->bih), sizeof(BitmapInfoHeader)); out.write((char*)(bitmap), bih.sizeimage); out.close(); std::cout << "OK!" << std::endl; return 0; } void Image::free() { delete[] this->bitmap; this->bitmap = nullptr; this->row_size = 0; this->bfh = BitmapFileHeader(); this->bih = BitmapInfoHeader(); } void Image::header(Image& img) { delete[] this->bitmap; this->bitmap = new byte_t[img.bih.sizeimage]; this->row_size = img.row_size; this->bfh = img.bfh; this->bih = img.bih; } Image& Image::operator = (Image& img) { delete[] this->bitmap; this->bitmap = new byte_t[img.bih.sizeimage]; std::copy_n(img.bitmap, img.bih.sizeimage, this->bitmap); this->row_size = img.row_size; this->bfh = img.bfh; this->bih = img.bih; return img; } Image& Image::operator = (Image&& img) noexcept { delete[] this->bitmap; this->bitmap = img.bitmap; this->row_size = img.row_size; this->bfh = img.bfh; this->bih = img.bih; return *this; } byte_t& Image::xyz(int64_t x, int64_t y, int64_t z) { x = lader(x, (int64_t)0, (int64_t)this->bih.width - 1); y = lader(y, (int64_t)0, (int64_t)this->bih.height - 1); return this->bitmap[y * this->row_size + x * 3 + z]; } void each(Image& src, byte_t(*func)(byte_t)) { Image dst; dst.header(src); for (size_t i = 0; i < src.bih.sizeimage; i++) dst.bitmap[i] = func(src.bitmap[i]); src = std::move(dst); } template <typename ...T> void each(Image& src, byte_t(*func)(byte_t, T...), T... arg) { Image dst; dst.header(src); for (size_t i = 0; i < src.bih.sizeimage; i++) dst.bitmap[i] = func(src.bitmap[i], arg...); src = std::move(dst); } void dot(Image& src, double vec3[3]) { Image dst; dst.header(src); for (size_t x = 0; x < src.bih.width; x++) for (size_t y = 0; y < src.bih.height; y++) { double t = vec3[0] * src.xyz(x, y, 0) + vec3[1] * src.xyz(x, y, 1) + vec3[2] * src.xyz(x, y, 2); dst.xyz(x, y, 0) = byte_t(t + 0.5); dst.xyz(x, y, 1) = byte_t(t + 0.5); dst.xyz(x, y, 2) = byte_t(t + 0.5); } src = std::move(dst); } void dot(Image& src, double vec3[3], double(*func)(double)) { Image dst; dst.header(src); for (size_t x = 0; x < src.bih.width; x++) for (size_t y = 0; y < src.bih.height; y++) { double t = vec3[0] * src.xyz(x, y, 0) + vec3[1] * src.xyz(x, y, 1) + vec3[2] * src.xyz(x, y, 2); t = func(t); dst.xyz(x, y, 0) = byte_t(t + 0.5); dst.xyz(x, y, 1) = byte_t(t + 0.5); dst.xyz(x, y, 2) = byte_t(t + 0.5); } src = std::move(dst); } void convolution(Image& src, double mat3[3][3]) { Image dst; dst.header(src); for (int64_t x = 0; x < (int64_t)src.bih.width; x++) for (int64_t y = 0; y < (int64_t)src.bih.height; y++) for (int64_t z = 0; z < 3; z++) { double t = 0.0; for (int64_t dx = -1; dx <= 1; dx++) for (int64_t dy = -1; dy <= 1; dy++) t += mat3[dx + 1][dy + 1] * src.xyz(x + dx, y + dy, z); dst.xyz(x, y, z) = byte_t(t + 0.5); } src = std::move(dst); } void convolution(Image& src, double mat3[3][3], double(*func)(double)) { Image dst; dst.header(src); for (int64_t x = 0; x < (int64_t)src.bih.width; x++) for (int64_t y = 0; y < (int64_t)src.bih.height; y++) for (int64_t z = 0; z < 3; z++) { double t = 0.0; for (int64_t dx = -1; dx <= 1; dx++) for (int64_t dy = -1; dy <= 1; dy++) t += mat3[dx + 1][dy + 1] * src.xyz(x + dx, y + dy, z); t = func(t); dst.xyz(x, y, z) = byte_t(t + 0.5); } src = std::move(dst); } void sampler(Image& src, Point<double>(*func)(Point<double>)) { Image dst; dst.header(src); for (int64_t x = 0; x < src.bih.width; x++) for (int64_t y = 0; y < src.bih.height; y++) { Point<double> p = func(Point<double>((double)x / src.bih.width * 2.0 - 1.0, (double)y / src.bih.height * 2.0 - 1.0)); p = (p + 1.0) * 0.5 * Point<double>((double)src.bih.width, (double)src.bih.height); int64_t xi = floor_int(p.x); int64_t yi = floor_int(p.y); double xf = fract(p.x); double yf = fract(p.y); for (int64_t z = 0; z < 3; z++) { double t = src.xyz(xi, yi, z) * (1.0 - xf) * (1.0 - yf) + src.xyz(xi + 1, yi, z) * xf * (1.0 - yf) + src.xyz(xi, yi + 1, z) * (1.0 - xf) * yf + src.xyz(xi + 1, yi + 1, z) * xf * yf; dst.xyz(x, y, z) = byte_t(t + 0.5); } } src = std::move(dst); } template <typename ...T> void sampler(Image& src, Point<double>(*func)(Point<double>, T...), T...arg) { Image dst; dst.header(src); for (int64_t x = 0; x < src.bih.width; x++) for (int64_t y = 0; y < src.bih.height; y++) { Point<double> p = func(Point<double>((double)x / src.bih.width * 2.0 - 1.0, (double)y / src.bih.height * 2.0 - 1.0), arg...); p = (p + 1.0) * 0.5 * Point<double>((double)src.bih.width, (double)src.bih.height); int64_t xi = floor_int(p.x); int64_t yi = floor_int(p.y); double xf = fract(p.x); double yf = fract(p.y); for (int64_t z = 0; z < 3; z++) { double t = src.xyz(xi, yi, z) * (1.0 - xf) * (1.0 - yf) + src.xyz(xi + 1, yi, z) * xf * (1.0 - yf) + src.xyz(xi, yi + 1, z) * (1.0 - xf) * yf + src.xyz(xi + 1, yi + 1, z) * xf * yf; dst.xyz(x, y, z) = byte_t(t + 0.5); } } src = std::move(dst); }