* drawing api * add drawing test * yuv420sp drawing * enable simpleocv in webassembly buildtags/20210525
| @@ -1279,7 +1279,7 @@ jobs: | |||
| source emsdk/emsdk_env.sh | |||
| mkdir build && cd build | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install -DNCNN_VERSION_STRING="${{ needs.setup.outputs.VERSION }}" \ | |||
| -DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=OFF -DNCNN_AVX2=OFF \ | |||
| -DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_SIMPLEOCV=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=OFF -DNCNN_AVX2=OFF \ | |||
| -DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF -DNCNN_BUILD_BENCHMARK=OFF .. | |||
| cmake --build . -j 2 | |||
| cmake --build . --target install | |||
| @@ -1288,7 +1288,7 @@ jobs: | |||
| source emsdk/emsdk_env.sh | |||
| mkdir build-simd && cd build-simd | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install -DNCNN_VERSION_STRING="${{ needs.setup.outputs.VERSION }}" \ | |||
| -DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF \ | |||
| -DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_SIMPLEOCV=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF \ | |||
| -DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF -DNCNN_BUILD_BENCHMARK=OFF .. | |||
| cmake --build . -j 2 | |||
| cmake --build . --target install | |||
| @@ -1297,7 +1297,7 @@ jobs: | |||
| source emsdk/emsdk_env.sh | |||
| mkdir build-threads && cd build-threads | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install -DNCNN_VERSION_STRING="${{ needs.setup.outputs.VERSION }}" \ | |||
| -DNCNN_THREADS=ON -DNCNN_OPENMP=ON -DNCNN_SIMPLEOMP=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=OFF -DNCNN_AVX2=OFF \ | |||
| -DNCNN_THREADS=ON -DNCNN_OPENMP=ON -DNCNN_SIMPLEOMP=ON -DNCNN_SIMPLEOCV=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=OFF -DNCNN_AVX2=OFF \ | |||
| -DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF -DNCNN_BUILD_BENCHMARK=OFF .. | |||
| cmake --build . -j 2 | |||
| cmake --build . --target install | |||
| @@ -1306,7 +1306,7 @@ jobs: | |||
| source emsdk/emsdk_env.sh | |||
| mkdir build-simd-threads && cd build-simd-threads | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install -DNCNN_VERSION_STRING="${{ needs.setup.outputs.VERSION }}" \ | |||
| -DNCNN_THREADS=ON -DNCNN_OPENMP=ON -DNCNN_SIMPLEOMP=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF \ | |||
| -DNCNN_THREADS=ON -DNCNN_OPENMP=ON -DNCNN_SIMPLEOMP=ON -DNCNN_SIMPLEOCV=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF \ | |||
| -DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF -DNCNN_BUILD_BENCHMARK=OFF .. | |||
| cmake --build . -j 2 | |||
| cmake --build . --target install | |||
| @@ -25,7 +25,7 @@ jobs: | |||
| run: | | |||
| source emsdk/emsdk_env.sh | |||
| mkdir build-basic && cd build-basic | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=OFF -DNCNN_AVX2=OFF -DNCNN_BUILD_TESTS=ON .. | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_SIMPLEOCV=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=OFF -DNCNN_AVX2=OFF -DNCNN_BUILD_TESTS=ON .. | |||
| cmake --build . -j 2 | |||
| - name: test-basic | |||
| run: | | |||
| @@ -35,7 +35,7 @@ jobs: | |||
| run: | | |||
| source emsdk/emsdk_env.sh | |||
| mkdir build-simd && cd build-simd | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF -DNCNN_BUILD_TESTS=ON .. | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_SIMPLEOCV=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF -DNCNN_BUILD_TESTS=ON .. | |||
| cmake --build . -j 2 | |||
| - name: test-simd | |||
| run: | | |||
| @@ -45,7 +45,7 @@ jobs: | |||
| run: | | |||
| source emsdk/emsdk_env.sh | |||
| mkdir build-simd-omp && cd build-simd-omp | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DNCNN_THREADS=ON -DNCNN_OPENMP=ON -DNCNN_SIMPLEOMP=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF -DNCNN_BUILD_TESTS=ON .. | |||
| cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DNCNN_THREADS=ON -DNCNN_OPENMP=ON -DNCNN_SIMPLEOMP=ON -DNCNN_SIMPLEOCV=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF -DNCNN_BUILD_TESTS=ON .. | |||
| cmake --build . -j 2 | |||
| - name: test-simd-omp | |||
| run: | | |||
| @@ -7,6 +7,9 @@ pull_requests: true | |||
| commit_template: | | |||
| [skip ci] Restyled by ${restyler.name} | |||
| exclude: | |||
| - "src/stb_image*" | |||
| statuses: | |||
| differences: true | |||
| no_differences: true | |||
| @@ -70,6 +70,7 @@ option(NCNN_PLATFORM_API "build with platform api candy" ON) | |||
| option(NCNN_PIXEL "convert and resize from/to image pixel" ON) | |||
| option(NCNN_PIXEL_ROTATE "rotate image pixel orientation" ON) | |||
| option(NCNN_PIXEL_AFFINE "warp affine image pixel" ON) | |||
| option(NCNN_PIXEL_DRAWING "draw basic figure and text" ON) | |||
| option(NCNN_CMAKE_VERBOSE "print verbose cmake messages" OFF) | |||
| option(NCNN_VULKAN "vulkan compute support" OFF) | |||
| option(NCNN_SYSTEM_GLSLANG "use system glslang library" OFF) | |||
| @@ -2,10 +2,12 @@ | |||
| # we run clang-format and astyle twice to get stable format output | |||
| find src/ tools/ tests/ examples/ benchmark/ python/ -type f -name '*.c' -o -name '*.cpp' -o -name '*.cc' -o -name '*.h' | grep -v python/pybind11 | xargs -i clang-format -i {} | |||
| astyle -n -r "benchmark/*.h,*.cpp,*.cc" "src/*.h,*.cpp,*.cc" "tests/*.h,*.cpp,*.cc" "tools/*.h,*.cpp,*.cc" "examples/*.h,*.cpp,*.cc" | |||
| find src/ tools/ tests/ examples/ benchmark/ python/ -type f -name '*.c' -o -name '*.cpp' -o -name '*.cc' -o -name '*.h' | grep -v python/pybind11 | grep -v stb_image | xargs -i clang-format -i {} | |||
| astyle -n -r "benchmark/*.h,*.cpp,*.cc" "tests/*.h,*.cpp,*.cc" "tools/*.h,*.cpp,*.cc" "examples/*.h,*.cpp,*.cc" | |||
| astyle -n -r "src/*.h,*.cpp,*.cc" --exclude=src/stb_image.h --exclude=src/stb_image_write.h | |||
| astyle -n -r "python/*.h,*.cpp,*.cc" --exclude=python/pybind11 | |||
| find src/ tools/ tests/ examples/ benchmark/ python/ -type f -name '*.c' -o -name '*.cpp' -o -name '*.cc' -o -name '*.h' | grep -v python/pybind11 | xargs -i clang-format -i {} | |||
| astyle -n -r "benchmark/*.h,*.cpp,*.cc" "src/*.h,*.cpp,*.cc" "tests/*.h,*.cpp,*.cc" "tools/*.h,*.cpp,*.cc" "examples/*.h,*.cpp,*.cc" | |||
| find src/ tools/ tests/ examples/ benchmark/ python/ -type f -name '*.c' -o -name '*.cpp' -o -name '*.cc' -o -name '*.h' | grep -v python/pybind11 | grep -v stb_image | xargs -i clang-format -i {} | |||
| astyle -n -r "benchmark/*.h,*.cpp,*.cc" "tests/*.h,*.cpp,*.cc" "tools/*.h,*.cpp,*.cc" "examples/*.h,*.cpp,*.cc" | |||
| astyle -n -r "src/*.h,*.cpp,*.cc" --exclude=src/stb_image.h --exclude=src/stb_image_write.h | |||
| astyle -n -r "python/*.h,*.cpp,*.cc" --exclude=python/pybind11 | |||
| @@ -27,6 +27,7 @@ set(ncnn_SRCS | |||
| mat.cpp | |||
| mat_pixel.cpp | |||
| mat_pixel_affine.cpp | |||
| mat_pixel_drawing.cpp | |||
| mat_pixel_resize.cpp | |||
| mat_pixel_rotate.cpp | |||
| modelbin.cpp | |||
| @@ -601,6 +601,58 @@ NCNN_EXPORT void warpaffine_bilinear_c4(const unsigned char* src, int srcw, int | |||
| // image pixel bilinear warpaffine, convenient wrapper for yuv420sp(nv21/nv12), set -233 for transparent border color, the color YUV_ is little-endian encoded | |||
| NCNN_EXPORT void warpaffine_bilinear_yuv420sp(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h, const float* tm, int type = 0, unsigned int v = 0); | |||
| #endif // NCNN_PIXEL_AFFINE | |||
| #if NCNN_PIXEL_DRAWING | |||
| // draw rectangle, set thickness -1 for filled rectangle, the color RGBA is little-endian encoded | |||
| NCNN_EXPORT void draw_rectangle_c1(unsigned char* pixels, int w, int h, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_rectangle_c2(unsigned char* pixels, int w, int h, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_rectangle_c3(unsigned char* pixels, int w, int h, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_rectangle_c4(unsigned char* pixels, int w, int h, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| // draw rectangle with stride(bytes-per-row) parameter, set thickness -1 for filled rectangle, the color RGBA is little-endian encoded | |||
| NCNN_EXPORT void draw_rectangle_c1(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_rectangle_c2(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_rectangle_c3(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_rectangle_c4(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| // draw rectangle, convenient wrapper for yuv420sp(nv21/nv12), set thickness -1 for filled rectangle, the color YUV_ is little-endian encoded | |||
| NCNN_EXPORT void draw_rectangle_yuv420sp(unsigned char* yuv420sp, int w, int h, int rx, int ry, int rw, int rh, unsigned int color, int thickness); | |||
| // draw circle, set thickness -1 for filled circle, the color RGBA is little-endian encoded | |||
| NCNN_EXPORT void draw_circle_c1(unsigned char* pixels, int w, int h, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_circle_c2(unsigned char* pixels, int w, int h, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_circle_c3(unsigned char* pixels, int w, int h, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_circle_c4(unsigned char* pixels, int w, int h, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| // draw circle with stride(bytes-per-row) parameter, set thickness -1 for filled circle, the color RGBA is little-endian encoded | |||
| NCNN_EXPORT void draw_circle_c1(unsigned char* pixels, int w, int h, int stride, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_circle_c2(unsigned char* pixels, int w, int h, int stride, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_circle_c3(unsigned char* pixels, int w, int h, int stride, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_circle_c4(unsigned char* pixels, int w, int h, int stride, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| // draw circle, convenient wrapper for yuv420sp(nv21/nv12), set thickness -1 for filled circle, the color YUV_ is little-endian encoded | |||
| NCNN_EXPORT void draw_circle_yuv420sp(unsigned char* yuv420sp, int w, int h, int cx, int cy, int radius, unsigned int color, int thickness); | |||
| // draw line, the color RGBA is little-endian encoded | |||
| NCNN_EXPORT void draw_line_c1(unsigned char* pixels, int w, int h, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_line_c2(unsigned char* pixels, int w, int h, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_line_c3(unsigned char* pixels, int w, int h, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_line_c4(unsigned char* pixels, int w, int h, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| // draw line with stride(bytes-per-row) parameter, the color RGBA is little-endian encoded | |||
| NCNN_EXPORT void draw_line_c1(unsigned char* pixels, int w, int h, int stride, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_line_c2(unsigned char* pixels, int w, int h, int stride, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_line_c3(unsigned char* pixels, int w, int h, int stride, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| NCNN_EXPORT void draw_line_c4(unsigned char* pixels, int w, int h, int stride, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| // draw line, convenient wrapper for yuv420sp(nv21/nv12), the color YUV_ is little-endian encoded | |||
| NCNN_EXPORT void draw_line_yuv420sp(unsigned char* yuv420sp, int w, int h, int x0, int y0, int x1, int y1, unsigned int color, int thickness); | |||
| // resolve text bounding box size | |||
| NCNN_EXPORT void get_text_drawing_size(const char* text, int fontpixelsize, int* w, int* h); | |||
| // draw ascii printables and newline, the color RGBA is little-endian encoded | |||
| NCNN_EXPORT void draw_text_c1(unsigned char* pixels, int w, int h, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| NCNN_EXPORT void draw_text_c2(unsigned char* pixels, int w, int h, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| NCNN_EXPORT void draw_text_c3(unsigned char* pixels, int w, int h, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| NCNN_EXPORT void draw_text_c4(unsigned char* pixels, int w, int h, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| // draw ascii printables and newline with stride(bytes-per-row) parameter, the color RGBA is little-endian encoded | |||
| NCNN_EXPORT void draw_text_c1(unsigned char* pixels, int w, int h, int stride, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| NCNN_EXPORT void draw_text_c2(unsigned char* pixels, int w, int h, int stride, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| NCNN_EXPORT void draw_text_c3(unsigned char* pixels, int w, int h, int stride, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| NCNN_EXPORT void draw_text_c4(unsigned char* pixels, int w, int h, int stride, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| // draw ascii printables and newline, convenient wrapper for yuv420sp(nv21/nv12), the color YUV_ is little-endian encoded | |||
| NCNN_EXPORT void draw_text_yuv420sp(unsigned char* yuv420sp, int w, int h, const char* text, int x, int y, int fontpixelsize, unsigned int color); | |||
| #endif // NCNN_PIXEL_DRAWING | |||
| // type conversion | |||
| // convert float to half precision floating point | |||
| @@ -26,6 +26,7 @@ | |||
| #cmakedefine01 NCNN_PIXEL | |||
| #cmakedefine01 NCNN_PIXEL_ROTATE | |||
| #cmakedefine01 NCNN_PIXEL_AFFINE | |||
| #cmakedefine01 NCNN_PIXEL_DRAWING | |||
| #cmakedefine01 NCNN_VULKAN | |||
| #cmakedefine01 NCNN_RUNTIME_CPU | |||
| #cmakedefine01 NCNN_AVX2 | |||
| @@ -18,65 +18,197 @@ | |||
| #include <stdio.h> | |||
| #define STB_IMAGE_IMPLEMENTATION | |||
| #define STBI_NO_THREAD_LOCALS | |||
| #define STBI_ONLY_JPEG | |||
| #define STBI_ONLY_PNG | |||
| #define STBI_ONLY_BMP | |||
| #define STBI_ONLY_PNM | |||
| #include "stb_image.h" | |||
| #define STB_IMAGE_WRITE_IMPLEMENTATION | |||
| #include "stb_image_write.h" | |||
| namespace cv { | |||
| Mat imread(const std::string& path, int flags) | |||
| { | |||
| (void)flags; | |||
| int desired_channels = 0; | |||
| if (flags == IMREAD_UNCHANGED) | |||
| { | |||
| desired_channels = 0; | |||
| } | |||
| else if (flags == IMREAD_GRAYSCALE) | |||
| { | |||
| desired_channels = 1; | |||
| } | |||
| else if (flags == IMREAD_COLOR) | |||
| { | |||
| desired_channels = 3; | |||
| } | |||
| else | |||
| { | |||
| // unknown flags | |||
| return Mat(); | |||
| } | |||
| // read pgm/ppm | |||
| FILE* fp = fopen(path.c_str(), "rb"); | |||
| if (!fp) | |||
| int w; | |||
| int h; | |||
| int c; | |||
| unsigned char* pixeldata = stbi_load(path.c_str(), &w, &h, &c, desired_channels); | |||
| if (!pixeldata) | |||
| { | |||
| // load failed | |||
| return Mat(); | |||
| } | |||
| Mat m; | |||
| if (desired_channels) | |||
| { | |||
| c = desired_channels; | |||
| } | |||
| char magic[3]; | |||
| int w, h; | |||
| int nscan = fscanf(fp, "%2s\n%d %d\n255\n", magic, &w, &h); | |||
| if (nscan == 3 && magic[0] == 'P' && (magic[1] == '5' || magic[1] == '6')) | |||
| // copy pixeldata to Mat | |||
| Mat img; | |||
| if (c == 1) | |||
| { | |||
| if (magic[1] == '5') | |||
| { | |||
| m.create(h, w, CV_8UC1); | |||
| } | |||
| else if (magic[1] == '6') | |||
| img.create(h, w, CV_8UC1); | |||
| } | |||
| else if (c == 3) | |||
| { | |||
| img.create(h, w, CV_8UC3); | |||
| } | |||
| else if (c == 4) | |||
| { | |||
| img.create(h, w, CV_8UC4); | |||
| } | |||
| else | |||
| { | |||
| // unexpected channels | |||
| stbi_image_free(pixeldata); | |||
| return Mat(); | |||
| } | |||
| memcpy(img.data, pixeldata, w * h * c); | |||
| stbi_image_free(pixeldata); | |||
| // // resolve exif orientation | |||
| // { | |||
| // std::ifstream ifs; | |||
| // ifs.open(filename.c_str(), std::ifstream::in); | |||
| // | |||
| // if (ifs.good()) | |||
| // { | |||
| // ExifReader exif_reader(ifs); | |||
| // if (exif_reader.parse()) | |||
| // { | |||
| // ExifEntry_t e = exif_reader.getTag(ORIENTATION); | |||
| // int orientation = e.field_u16; | |||
| // if (orientation >= 1 && orientation <= 8) | |||
| // rotate_by_orientation(img, img, orientation); | |||
| // } | |||
| // } | |||
| // | |||
| // ifs.close(); | |||
| // } | |||
| // rgb to bgr | |||
| if (c == 3) | |||
| { | |||
| uchar* p = img.data; | |||
| for (int i = 0; i < w * h; i++) | |||
| { | |||
| m.create(h, w, CV_8UC3); | |||
| std::swap(p[0], p[2]); | |||
| p += 3; | |||
| } | |||
| if (m.empty()) | |||
| } | |||
| if (c == 4) | |||
| { | |||
| uchar* p = img.data; | |||
| for (int i = 0; i < w * h; i++) | |||
| { | |||
| fclose(fp); | |||
| return Mat(); | |||
| std::swap(p[0], p[2]); | |||
| p += 4; | |||
| } | |||
| fread(m.data, 1, m.total(), fp); | |||
| } | |||
| fclose(fp); | |||
| return m; | |||
| return img; | |||
| } | |||
| void imwrite(const std::string& path, const Mat& m) | |||
| bool imwrite(const std::string& path, const Mat& m, const std::vector<int>& params) | |||
| { | |||
| // write pgm/ppm | |||
| FILE* fp = fopen(path.c_str(), "wb"); | |||
| if (!fp) | |||
| return; | |||
| const char* _ext = strrchr(path.c_str(), '.'); | |||
| if (!_ext) | |||
| { | |||
| // missing extension | |||
| return false; | |||
| } | |||
| std::string ext = _ext; | |||
| Mat img = m.clone(); | |||
| if (m.channels() == 1) | |||
| // bgr to rgb | |||
| int c = 0; | |||
| if (img.type() == CV_8UC1) | |||
| { | |||
| fprintf(fp, "P5\n%d %d\n255\n", m.cols, m.rows); | |||
| c = 1; | |||
| } | |||
| else if (m.channels() == 3) | |||
| else if (img.type() == CV_8UC3) | |||
| { | |||
| fprintf(fp, "P6\n%d %d\n255\n", m.cols, m.rows); | |||
| c = 3; | |||
| uchar* p = img.data; | |||
| for (int i = 0; i < img.cols * img.rows; i++) | |||
| { | |||
| std::swap(p[0], p[2]); | |||
| p += 3; | |||
| } | |||
| } | |||
| else if (img.type() == CV_8UC4) | |||
| { | |||
| c = 4; | |||
| uchar* p = img.data; | |||
| for (int i = 0; i < img.cols * img.rows; i++) | |||
| { | |||
| std::swap(p[0], p[2]); | |||
| p += 4; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| // unexpected image channels | |||
| return false; | |||
| } | |||
| bool success = false; | |||
| fwrite(m.data, 1, m.total(), fp); | |||
| if (ext == ".jpg" || ext == ".jpeg" || ext == ".JPG" || ext == ".JPEG") | |||
| { | |||
| int quality = 95; | |||
| for (size_t i = 0; i < params.size(); i += 2) | |||
| { | |||
| if (params[i] == IMWRITE_JPEG_QUALITY) | |||
| { | |||
| quality = params[i + 1]; | |||
| break; | |||
| } | |||
| } | |||
| success = stbi_write_jpg(path.c_str(), img.cols, img.rows, c, img.data, quality); | |||
| } | |||
| else if (ext == ".png" || ext == ".PNG") | |||
| { | |||
| success = stbi_write_png(path.c_str(), img.cols, img.rows, c, img.data, 0); | |||
| } | |||
| else if (ext == ".bmp" || ext == ".BMP") | |||
| { | |||
| success = stbi_write_bmp(path.c_str(), img.cols, img.rows, c, img.data); | |||
| } | |||
| else | |||
| { | |||
| // unknown extension type | |||
| return false; | |||
| } | |||
| fclose(fp); | |||
| return success; | |||
| } | |||
| #if NCNN_PIXEL | |||
| @@ -120,6 +252,143 @@ void resize(const Mat& src, Mat& dst, const Size& size, float sw, float sh, int | |||
| } | |||
| #endif // NCNN_PIXEL | |||
| #if NCNN_PIXEL_DRAWING | |||
| void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness) | |||
| { | |||
| Rect rec; | |||
| rec.x = std::min(pt1.x, pt2.x); | |||
| rec.y = std::min(pt1.y, pt2.y); | |||
| rec.width = std::max(pt1.x, pt2.x) - rec.x; | |||
| rec.height = std::max(pt1.y, pt2.y) - rec.y; | |||
| rectangle(img, rec, color, thickness); | |||
| } | |||
| void rectangle(Mat& img, Rect rec, const Scalar& _color, int thickness) | |||
| { | |||
| unsigned int color = 0; | |||
| unsigned char* border_color = (unsigned char*)&color; | |||
| if (img.c == 1) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| ncnn::draw_rectangle_c1(img.data, img.cols, img.rows, rec.x, rec.y, rec.width, rec.height, color, thickness); | |||
| } | |||
| else if (img.c == 3) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| border_color[1] = _color[1]; | |||
| border_color[2] = _color[2]; | |||
| ncnn::draw_rectangle_c3(img.data, img.cols, img.rows, rec.x, rec.y, rec.width, rec.height, color, thickness); | |||
| } | |||
| else if (img.c == 4) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| border_color[1] = _color[1]; | |||
| border_color[2] = _color[2]; | |||
| border_color[3] = _color[3]; | |||
| ncnn::draw_rectangle_c4(img.data, img.cols, img.rows, rec.x, rec.y, rec.width, rec.height, color, thickness); | |||
| } | |||
| } | |||
| void circle(Mat& img, Point center, int radius, const Scalar& _color, int thickness) | |||
| { | |||
| unsigned int color = 0; | |||
| unsigned char* border_color = (unsigned char*)&color; | |||
| if (img.c == 1) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| ncnn::draw_circle_c1(img.data, img.cols, img.rows, center.x, center.y, radius, color, thickness); | |||
| } | |||
| else if (img.c == 3) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| border_color[1] = _color[1]; | |||
| border_color[2] = _color[2]; | |||
| ncnn::draw_circle_c3(img.data, img.cols, img.rows, center.x, center.y, radius, color, thickness); | |||
| } | |||
| else if (img.c == 4) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| border_color[1] = _color[1]; | |||
| border_color[2] = _color[2]; | |||
| border_color[3] = _color[3]; | |||
| ncnn::draw_circle_c4(img.data, img.cols, img.rows, center.x, center.y, radius, color, thickness); | |||
| } | |||
| } | |||
| void line(Mat& img, Point p0, Point p1, const Scalar& _color, int thickness) | |||
| { | |||
| unsigned int color = 0; | |||
| unsigned char* border_color = (unsigned char*)&color; | |||
| if (img.c == 1) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| ncnn::draw_line_c1(img.data, img.cols, img.rows, p0.x, p0.y, p1.x, p1.y, color, thickness); | |||
| } | |||
| else if (img.c == 3) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| border_color[1] = _color[1]; | |||
| border_color[2] = _color[2]; | |||
| ncnn::draw_line_c3(img.data, img.cols, img.rows, p0.x, p0.y, p1.x, p1.y, color, thickness); | |||
| } | |||
| else if (img.c == 4) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| border_color[1] = _color[1]; | |||
| border_color[2] = _color[2]; | |||
| border_color[3] = _color[3]; | |||
| ncnn::draw_line_c4(img.data, img.cols, img.rows, p0.x, p0.y, p1.x, p1.y, color, thickness); | |||
| } | |||
| } | |||
| void putText(Mat& img, const std::string& text, Point org, int fontFace, double fontScale, Scalar _color, int thickness) | |||
| { | |||
| const int fontpixelsize = 20 * fontScale; | |||
| unsigned int color = 0; | |||
| unsigned char* border_color = (unsigned char*)&color; | |||
| if (img.c == 1) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| ncnn::draw_text_c1(img.data, img.cols, img.rows, text.c_str(), org.x, org.y - fontpixelsize * 2, fontpixelsize, color); | |||
| } | |||
| else if (img.c == 3) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| border_color[1] = _color[1]; | |||
| border_color[2] = _color[2]; | |||
| ncnn::draw_text_c3(img.data, img.cols, img.rows, text.c_str(), org.x, org.y - fontpixelsize * 2, fontpixelsize, color); | |||
| } | |||
| else if (img.c == 4) | |||
| { | |||
| border_color[0] = _color[0]; | |||
| border_color[1] = _color[1]; | |||
| border_color[2] = _color[2]; | |||
| border_color[3] = _color[3]; | |||
| ncnn::draw_text_c4(img.data, img.cols, img.rows, text.c_str(), org.x, org.y - fontpixelsize * 2, fontpixelsize, color); | |||
| } | |||
| } | |||
| Size getTextSize(const std::string& text, int fontFace, double fontScale, int thickness, int* baseLine) | |||
| { | |||
| const int fontpixelsize = 20 * fontScale; | |||
| int w; | |||
| int h; | |||
| ncnn::get_text_drawing_size(text.c_str(), fontpixelsize, &w, &h); | |||
| *baseLine = 0; | |||
| return Size(w, h); | |||
| } | |||
| #endif // NCNN_PIXEL_DRAWING | |||
| } // namespace cv | |||
| #endif // NCNN_SIMPLEOCV | |||
| @@ -19,6 +19,9 @@ | |||
| #if NCNN_SIMPLEOCV | |||
| #include <limits.h> | |||
| #include <string.h> | |||
| #include "allocator.h" | |||
| #include "mat.h" | |||
| #if defined(_MSC_VER) || defined(__GNUC__) | |||
| @@ -28,24 +31,125 @@ | |||
| #undef max | |||
| #endif | |||
| #ifndef NCNN_XADD | |||
| using ncnn::NCNN_XADD; | |||
| #endif | |||
| typedef unsigned char uchar; | |||
| typedef unsigned short ushort; | |||
| typedef unsigned int uint; | |||
| enum | |||
| { | |||
| CV_LOAD_IMAGE_UNCHANGED = -1, | |||
| CV_LOAD_IMAGE_GRAYSCALE = 0, | |||
| CV_LOAD_IMAGE_COLOR = 1, | |||
| }; | |||
| enum | |||
| { | |||
| CV_IMWRITE_JPEG_QUALITY = 1 | |||
| }; | |||
| // minimal opencv style data structure implementation | |||
| namespace cv { | |||
| struct NCNN_EXPORT Size | |||
| template<typename _Tp> | |||
| static inline _Tp saturate_cast(int v) | |||
| { | |||
| return _Tp(v); | |||
| } | |||
| template<> | |||
| inline uchar saturate_cast<uchar>(int v) | |||
| { | |||
| return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); | |||
| } | |||
| template<typename _Tp> | |||
| struct Scalar_ | |||
| { | |||
| Size() | |||
| Scalar_() | |||
| { | |||
| v[0] = 0; | |||
| v[1] = 0; | |||
| v[2] = 0; | |||
| v[3] = 0; | |||
| } | |||
| Scalar_(_Tp _v0) | |||
| { | |||
| v[0] = _v0; | |||
| v[1] = 0; | |||
| v[2] = 0; | |||
| v[3] = 0; | |||
| } | |||
| Scalar_(_Tp _v0, _Tp _v1, _Tp _v2) | |||
| { | |||
| v[0] = _v0; | |||
| v[1] = _v1; | |||
| v[2] = _v2; | |||
| v[3] = 0; | |||
| } | |||
| Scalar_(_Tp _v0, _Tp _v1, _Tp _v2, _Tp _v3) | |||
| { | |||
| v[0] = _v0; | |||
| v[1] = _v1; | |||
| v[2] = _v2; | |||
| v[3] = _v3; | |||
| } | |||
| const _Tp operator[](const int i) const | |||
| { | |||
| return v[i]; | |||
| } | |||
| _Tp operator[](const int i) | |||
| { | |||
| return v[i]; | |||
| } | |||
| _Tp v[4]; | |||
| }; | |||
| typedef Scalar_<uchar> Scalar; | |||
| template<typename _Tp> | |||
| struct Point_ | |||
| { | |||
| Point_() | |||
| : x(0), y(0) | |||
| { | |||
| } | |||
| Point_(_Tp _x, _Tp _y) | |||
| : x(_x), y(_y) | |||
| { | |||
| } | |||
| _Tp x; | |||
| _Tp y; | |||
| }; | |||
| typedef Point_<int> Point; | |||
| typedef Point_<float> Point2f; | |||
| template<typename _Tp> | |||
| struct Size_ | |||
| { | |||
| Size_() | |||
| : width(0), height(0) | |||
| { | |||
| } | |||
| Size(int _w, int _h) | |||
| Size_(_Tp _w, _Tp _h) | |||
| : width(_w), height(_h) | |||
| { | |||
| } | |||
| int width; | |||
| int height; | |||
| _Tp width; | |||
| _Tp height; | |||
| }; | |||
| typedef Size_<int> Size; | |||
| typedef Size_<float> Size2f; | |||
| template<typename _Tp> | |||
| struct Rect_ | |||
| { | |||
| @@ -57,6 +161,10 @@ struct Rect_ | |||
| : x(_x), y(_y), width(_w), height(_h) | |||
| { | |||
| } | |||
| Rect_(Point_<_Tp> _p, Size_<_Tp> _size) | |||
| : x(_p.x), y(_p.y), width(_size.width), height(_size.height) | |||
| { | |||
| } | |||
| _Tp x; | |||
| _Tp y; | |||
| @@ -111,25 +219,6 @@ static inline Rect_<_Tp> operator|(const Rect_<_Tp>& a, const Rect_<_Tp>& b) | |||
| typedef Rect_<int> Rect; | |||
| typedef Rect_<float> Rect2f; | |||
| template<typename _Tp> | |||
| struct Point_ | |||
| { | |||
| Point_() | |||
| : x(0), y(0) | |||
| { | |||
| } | |||
| Point_(_Tp _x, _Tp _y) | |||
| : x(_x), y(_y) | |||
| { | |||
| } | |||
| _Tp x; | |||
| _Tp y; | |||
| }; | |||
| typedef Point_<int> Point; | |||
| typedef Point_<float> Point2f; | |||
| #define CV_8UC1 1 | |||
| #define CV_8UC3 3 | |||
| #define CV_8UC4 4 | |||
| @@ -194,6 +283,23 @@ struct NCNN_EXPORT Mat | |||
| return *this; | |||
| } | |||
| Mat& operator=(const Scalar& s) | |||
| { | |||
| if (total() > 0) | |||
| { | |||
| uchar* p = data; | |||
| for (int i = 0; i < cols * rows; i++) | |||
| { | |||
| for (int j = 0; j < c; j++) | |||
| { | |||
| *p++ = s[j]; | |||
| } | |||
| } | |||
| } | |||
| return *this; | |||
| } | |||
| void create(int _rows, int _cols, int flags) | |||
| { | |||
| release(); | |||
| @@ -206,8 +312,8 @@ struct NCNN_EXPORT Mat | |||
| { | |||
| // refcount address must be aligned, so we expand totalsize here | |||
| size_t totalsize = (total() + 3) >> 2 << 2; | |||
| data = (unsigned char*)ncnn::fastMalloc(totalsize + (int)sizeof(*refcount)); | |||
| refcount = (int*)(((unsigned char*)data) + totalsize); | |||
| data = (uchar*)ncnn::fastMalloc(totalsize + (int)sizeof(*refcount)); | |||
| refcount = (int*)(((uchar*)data) + totalsize); | |||
| *refcount = 1; | |||
| } | |||
| } | |||
| @@ -251,21 +357,38 @@ struct NCNN_EXPORT Mat | |||
| return c; | |||
| } | |||
| int type() const | |||
| { | |||
| return c; | |||
| } | |||
| size_t total() const | |||
| { | |||
| return cols * rows * c; | |||
| } | |||
| const unsigned char* ptr(int y) const | |||
| const uchar* ptr(int y) const | |||
| { | |||
| return data + y * cols * c; | |||
| } | |||
| unsigned char* ptr(int y) | |||
| uchar* ptr(int y) | |||
| { | |||
| return data + y * cols * c; | |||
| } | |||
| template<typename _Tp> | |||
| const _Tp* ptr(int y) const | |||
| { | |||
| return (const _Tp*)data + y * cols * c; | |||
| } | |||
| template<typename _Tp> | |||
| _Tp* ptr(int y) | |||
| { | |||
| return (_Tp*)data + y * cols * c; | |||
| } | |||
| // roi | |||
| Mat operator()(const Rect& roi) const | |||
| { | |||
| @@ -277,8 +400,8 @@ struct NCNN_EXPORT Mat | |||
| int sy = roi.y; | |||
| for (int y = 0; y < roi.height; y++) | |||
| { | |||
| const unsigned char* sptr = ptr(sy) + roi.x * c; | |||
| unsigned char* dptr = m.ptr(y); | |||
| const uchar* sptr = ptr(sy) + roi.x * c; | |||
| uchar* dptr = m.ptr(y); | |||
| memcpy(dptr, sptr, roi.width * c); | |||
| sy++; | |||
| } | |||
| @@ -286,7 +409,7 @@ struct NCNN_EXPORT Mat | |||
| return m; | |||
| } | |||
| unsigned char* data; | |||
| uchar* data; | |||
| // pointer to the reference counter; | |||
| // when points to user-allocated data, the pointer is NULL | |||
| @@ -298,15 +421,52 @@ struct NCNN_EXPORT Mat | |||
| int c; | |||
| }; | |||
| #define CV_LOAD_IMAGE_GRAYSCALE 1 | |||
| #define CV_LOAD_IMAGE_COLOR 3 | |||
| NCNN_EXPORT Mat imread(const std::string& path, int flags); | |||
| NCNN_EXPORT void imwrite(const std::string& path, const Mat& m); | |||
| enum ImreadModes | |||
| { | |||
| IMREAD_UNCHANGED = -1, | |||
| IMREAD_GRAYSCALE = 0, | |||
| IMREAD_COLOR = 1 | |||
| }; | |||
| NCNN_EXPORT Mat imread(const std::string& path, int flags = IMREAD_COLOR); | |||
| enum ImwriteFlags | |||
| { | |||
| IMWRITE_JPEG_QUALITY = 1 | |||
| }; | |||
| NCNN_EXPORT bool imwrite(const std::string& path, const Mat& m, const std::vector<int>& params = std::vector<int>()); | |||
| #if NCNN_PIXEL | |||
| NCNN_EXPORT void resize(const Mat& src, Mat& dst, const Size& size, float sw = 0.f, float sh = 0.f, int flags = 0); | |||
| #endif // NCNN_PIXEL | |||
| #if NCNN_PIXEL_DRAWING | |||
| enum | |||
| { | |||
| FILLED = -1 | |||
| }; | |||
| NCNN_EXPORT void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness = 1); | |||
| NCNN_EXPORT void rectangle(Mat& img, Rect rec, const Scalar& color, int thickness = 1); | |||
| NCNN_EXPORT void circle(Mat& img, Point center, int radius, const Scalar& color, int thickness = 1); | |||
| NCNN_EXPORT void line(Mat& img, Point p0, Point p1, const Scalar& color, int thickness = 1); | |||
| enum | |||
| { | |||
| FONT_HERSHEY_SIMPLEX = 0 | |||
| }; | |||
| NCNN_EXPORT void putText(Mat& img, const std::string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness = 1); | |||
| NCNN_EXPORT Size getTextSize(const std::string& text, int fontFace, double fontScale, int thickness, int* baseLine); | |||
| #endif // NCNN_PIXEL_DRAWING | |||
| } // namespace cv | |||
| #if defined(_MSC_VER) || defined(__GNUC__) | |||
| @@ -30,6 +30,10 @@ if(NCNN_PIXEL_AFFINE) | |||
| ncnn_add_test(mat_pixel_affine) | |||
| endif() | |||
| if(NCNN_PIXEL_DRAWING) | |||
| ncnn_add_test(mat_pixel_drawing) | |||
| endif() | |||
| if(NCNN_PIXEL_ROTATE) | |||
| ncnn_add_test(mat_pixel_rotate) | |||
| endif() | |||
| @@ -0,0 +1,753 @@ | |||
| // Tencent is pleased to support the open source community by making ncnn available. | |||
| // | |||
| // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. | |||
| // | |||
| // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except | |||
| // in compliance with the License. You may obtain a copy of the License at | |||
| // | |||
| // https://opensource.org/licenses/BSD-3-Clause | |||
| // | |||
| // Unless required by applicable law or agreed to in writing, software distributed | |||
| // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |||
| // CONDITIONS OF ANY KIND, either express or implied. See the License for the | |||
| // specific language governing permissions and limitations under the License. | |||
| #include "mat.h" | |||
| #include "prng.h" | |||
| #include <string.h> | |||
| static struct prng_rand_t g_prng_rand_state; | |||
| #define SRAND(seed) prng_srand(seed, &g_prng_rand_state) | |||
| #define RAND() prng_rand(&g_prng_rand_state) | |||
| static int RandomInt(int a, int b) | |||
| { | |||
| float random = ((float)RAND()) / (float)uint64_t(-1); //RAND_MAX; | |||
| int diff = b - a; | |||
| float r = random * diff; | |||
| return a + (int)r; | |||
| } | |||
| static int RandomInt2(int a, int b) | |||
| { | |||
| float random = ((float)RAND()) / (float)uint64_t(-1); //RAND_MAX; | |||
| int diff = b - a; | |||
| float r = random * diff; | |||
| return (a + (int)r + 1) / 2 * 2; | |||
| } | |||
| static int test_mat_pixel_drawing_c1(int w, int h) | |||
| { | |||
| ncnn::Mat a(w, h, 1u, 1); | |||
| ncnn::Mat b(h, w, 1u, 1); | |||
| int _color = 0; | |||
| unsigned char* color = (unsigned char*)&_color; | |||
| // fill with color | |||
| color[0] = 255; | |||
| ncnn::draw_rectangle_c1(a, w, h, 0, 0, w, h, _color, -1); | |||
| ncnn::draw_rectangle_c1(b, h, w, 0, 0, h, w, _color, -1); | |||
| // draw rectangle | |||
| int rx = RandomInt(0, w); | |||
| int ry = RandomInt(0, h); | |||
| int rw = RandomInt(0, w - rx); | |||
| int rh = RandomInt(0, h - ry); | |||
| color[0] = 100; | |||
| ncnn::draw_rectangle_c1(a, w, h, rx, ry, rw, rh, _color, 3); | |||
| ncnn::draw_rectangle_c1(b, h, w, ry, rx, rh, rw, _color, 3); | |||
| // draw filled rectangle out of image | |||
| color[0] = 144; | |||
| ncnn::draw_rectangle_c1(a, w, h, w - 10, -10, 20, 30, _color, -1); | |||
| ncnn::draw_rectangle_c1(b, h, w, -10, w - 10, 30, 20, _color, -1); | |||
| color[0] = 166; | |||
| ncnn::draw_rectangle_c1(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 7); | |||
| ncnn::draw_rectangle_c1(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 7); | |||
| // draw rectangle out of image | |||
| color[0] = 44; | |||
| ncnn::draw_rectangle_c1(a, w, h, rx + w / 2, ry + h / 2, rw, rh, _color, 1); | |||
| ncnn::draw_rectangle_c1(b, h, w, ry + h / 2, rx + w / 2, rh, rw, _color, 1); | |||
| color[0] = 66; | |||
| ncnn::draw_rectangle_c1(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 7); | |||
| ncnn::draw_rectangle_c1(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 7); | |||
| // draw filled circle | |||
| int cx = RandomInt(0, w); | |||
| int cy = RandomInt(0, h); | |||
| int radius = RandomInt(0, std::min(w, h)); | |||
| color[0] = 20; | |||
| ncnn::draw_circle_c1(a, w, h, cx, cy, radius, _color, -1); | |||
| ncnn::draw_circle_c1(b, h, w, cy, cx, radius, _color, -1); | |||
| // draw filled circle out of image | |||
| color[0] = 230; | |||
| ncnn::draw_circle_c1(a, w, h, 10, -4, 6, _color, -1); | |||
| ncnn::draw_circle_c1(b, h, w, -4, 10, 6, _color, -1); | |||
| // draw circle out of image | |||
| color[0] = 130; | |||
| ncnn::draw_circle_c1(a, w, h, cx, cy, radius + std::min(w, h) / 2, _color, 5); | |||
| ncnn::draw_circle_c1(b, h, w, cy, cx, radius + std::min(w, h) / 2, _color, 5); | |||
| // draw line | |||
| int x0 = RandomInt(0, w); | |||
| int y0 = RandomInt(0, h); | |||
| int x1 = RandomInt(0, w); | |||
| int y1 = RandomInt(0, h); | |||
| color[0] = 233; | |||
| ncnn::draw_line_c1(a, w, h, x0, y0, x1, y1, _color, 7); | |||
| ncnn::draw_line_c1(b, h, w, y0, x0, y1, x1, _color, 7); | |||
| // draw line out of image | |||
| color[0] = 192; | |||
| ncnn::draw_line_c1(a, w, h, x0 - w, y0 - h, x1 + w, y1 + h, _color, 1); | |||
| ncnn::draw_line_c1(b, h, w, y0 - h, x0 - w, y1 + h, x1 + w, _color, 1); | |||
| // transpose b | |||
| ncnn::Mat c(w, h, 1u, 1); | |||
| ncnn::kanna_rotate_c1(b, h, w, c, w, h, 5); | |||
| // draw text | |||
| const char text[] = "saJIEWdl\nj43@o"; | |||
| int tx = RandomInt(0, w / 2); | |||
| int ty = RandomInt(0, h / 2); | |||
| int fontpixelsize = 10; | |||
| color[0] = 128; | |||
| ncnn::draw_text_c1(a, w, h, text, tx, ty, fontpixelsize, _color); | |||
| int tw; | |||
| int th; | |||
| ncnn::get_text_drawing_size(text, fontpixelsize, &tw, &th); | |||
| const int len = strlen(text); | |||
| for (int i = 0; i < 8; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c1(c, w, h, ch, tx + tw / 8 * i, ty, fontpixelsize, _color); | |||
| } | |||
| for (int i = 9; i < len; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c1(c, w, h, ch, tx + tw / 8 * (i - 9), ty + th / 2, fontpixelsize, _color); | |||
| } | |||
| // draw text out of image | |||
| fontpixelsize = std::max(w, h) / 2; | |||
| color[0] = 228; | |||
| ncnn::draw_text_c1(a, w, h, "QAQ", -3, -5, fontpixelsize, _color); | |||
| ncnn::get_text_drawing_size("QAQ", fontpixelsize, &tw, &th); | |||
| ncnn::draw_text_c1(c, w, h, "Q", -3, -5, fontpixelsize, _color); | |||
| ncnn::draw_text_c1(c, w, h, "A", -3 + tw / 3, -5, fontpixelsize, _color); | |||
| ncnn::draw_text_c1(c, w, h, "Q", -3 + tw / 3 * 2, -5, fontpixelsize, _color); | |||
| if (memcmp(a, c, w * h) != 0) | |||
| { | |||
| fprintf(stderr, "test_mat_pixel_drawing_c1 failed w=%d h=%d\n", w, h); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| static int test_mat_pixel_drawing_c2(int w, int h) | |||
| { | |||
| ncnn::Mat a(w, h, 2u, 2); | |||
| ncnn::Mat b(h, w, 2u, 2); | |||
| int _color = 0; | |||
| unsigned char* color = (unsigned char*)&_color; | |||
| // fill with color | |||
| color[0] = 255; | |||
| color[1] = 251; | |||
| ncnn::draw_rectangle_c2(a, w, h, 0, 0, w, h, _color, -1); | |||
| ncnn::draw_rectangle_c2(b, h, w, 0, 0, h, w, _color, -1); | |||
| // draw rectangle | |||
| int rx = RandomInt(0, w); | |||
| int ry = RandomInt(0, h); | |||
| int rw = RandomInt(0, w - rx); | |||
| int rh = RandomInt(0, h - ry); | |||
| color[0] = 100; | |||
| color[1] = 130; | |||
| ncnn::draw_rectangle_c2(a, w, h, rx, ry, rw, rh, _color, 3); | |||
| ncnn::draw_rectangle_c2(b, h, w, ry, rx, rh, rw, _color, 3); | |||
| // draw filled rectangle out of image | |||
| color[0] = 144; | |||
| color[1] = 133; | |||
| ncnn::draw_rectangle_c2(a, w, h, w - 10, -10, 20, 30, _color, -1); | |||
| ncnn::draw_rectangle_c2(b, h, w, -10, w - 10, 30, 20, _color, -1); | |||
| color[0] = 166; | |||
| color[1] = 133; | |||
| ncnn::draw_rectangle_c2(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 7); | |||
| ncnn::draw_rectangle_c2(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 7); | |||
| // draw rectangle out of image | |||
| color[0] = 44; | |||
| color[1] = 33; | |||
| ncnn::draw_rectangle_c2(a, w, h, rx + w / 2, ry + h / 2, rw, rh, _color, 1); | |||
| ncnn::draw_rectangle_c2(b, h, w, ry + h / 2, rx + w / 2, rh, rw, _color, 1); | |||
| color[0] = 66; | |||
| color[1] = 44; | |||
| ncnn::draw_rectangle_c2(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 7); | |||
| ncnn::draw_rectangle_c2(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 7); | |||
| // draw filled circle | |||
| int cx = RandomInt(0, w); | |||
| int cy = RandomInt(0, h); | |||
| int radius = RandomInt(0, std::min(w, h)); | |||
| color[0] = 20; | |||
| color[1] = 120; | |||
| ncnn::draw_circle_c2(a, w, h, cx, cy, radius, _color, -1); | |||
| ncnn::draw_circle_c2(b, h, w, cy, cx, radius, _color, -1); | |||
| // draw filled circle out of image | |||
| color[0] = 230; | |||
| color[1] = 130; | |||
| ncnn::draw_circle_c2(a, w, h, 10, -4, 6, _color, -1); | |||
| ncnn::draw_circle_c2(b, h, w, -4, 10, 6, _color, -1); | |||
| // draw circle out of image | |||
| color[0] = 130; | |||
| color[1] = 30; | |||
| ncnn::draw_circle_c2(a, w, h, cx, cy, radius + std::min(w, h) / 2, _color, 5); | |||
| ncnn::draw_circle_c2(b, h, w, cy, cx, radius + std::min(w, h) / 2, _color, 5); | |||
| // draw line | |||
| int x0 = RandomInt(0, w); | |||
| int y0 = RandomInt(0, h); | |||
| int x1 = RandomInt(0, w); | |||
| int y1 = RandomInt(0, h); | |||
| color[0] = 233; | |||
| color[1] = 233; | |||
| ncnn::draw_line_c2(a, w, h, x0, y0, x1, y1, _color, 7); | |||
| ncnn::draw_line_c2(b, h, w, y0, x0, y1, x1, _color, 7); | |||
| // draw line out of image | |||
| color[0] = 192; | |||
| color[1] = 192; | |||
| ncnn::draw_line_c2(a, w, h, x0 - w, y0 - h, x1 + w, y1 + h, _color, 1); | |||
| ncnn::draw_line_c2(b, h, w, y0 - h, x0 - w, y1 + h, x1 + w, _color, 1); | |||
| // transpose b | |||
| ncnn::Mat c(w, h, 2u, 2); | |||
| ncnn::kanna_rotate_c2(b, h, w, c, w, h, 5); | |||
| // draw text | |||
| const char text[] = "Q`~\\=f\nPN\'/<DSA"; | |||
| int tx = RandomInt(0, w / 2); | |||
| int ty = RandomInt(0, h / 2); | |||
| int fontpixelsize = 12; | |||
| color[0] = 0; | |||
| color[1] = 128; | |||
| ncnn::draw_text_c2(a, w, h, text, tx, ty, fontpixelsize, _color); | |||
| int tw; | |||
| int th; | |||
| ncnn::get_text_drawing_size(text, fontpixelsize, &tw, &th); | |||
| const int len = strlen(text); | |||
| for (int i = 0; i < 6; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c2(c, w, h, ch, tx + tw / 8 * i, ty, fontpixelsize, _color); | |||
| } | |||
| for (int i = 7; i < len; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c2(c, w, h, ch, tx + tw / 8 * (i - 7), ty + th / 2, fontpixelsize, _color); | |||
| } | |||
| // draw text out of image | |||
| fontpixelsize = std::max(w, h) / 3; | |||
| color[0] = 228; | |||
| color[1] = 0; | |||
| ncnn::draw_text_c2(a, w, h, "!@#$%^&", -1, -2, fontpixelsize, _color); | |||
| ncnn::get_text_drawing_size("!@#$%^&", fontpixelsize, &tw, &th); | |||
| ncnn::draw_text_c2(c, w, h, "!@#", -1, -2, fontpixelsize, _color); | |||
| ncnn::draw_text_c2(c, w, h, "$", -1 + tw / 7 * 3, -2, fontpixelsize, _color); | |||
| ncnn::draw_text_c2(c, w, h, "%^&", -1 + tw / 7 * 4, -2, fontpixelsize, _color); | |||
| if (memcmp(a, c, w * h * 2) != 0) | |||
| { | |||
| fprintf(stderr, "test_mat_pixel_drawing_c2 failed w=%d h=%d\n", w, h); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| static int test_mat_pixel_drawing_c3(int w, int h) | |||
| { | |||
| ncnn::Mat a(w, h, 3u, 3); | |||
| ncnn::Mat b(h, w, 3u, 3); | |||
| int _color = 0; | |||
| unsigned char* color = (unsigned char*)&_color; | |||
| // fill with color | |||
| color[0] = 255; | |||
| color[1] = 251; | |||
| color[2] = 244; | |||
| ncnn::draw_rectangle_c3(a, w, h, 0, 0, w, h, _color, -1); | |||
| ncnn::draw_rectangle_c3(b, h, w, 0, 0, h, w, _color, -1); | |||
| // draw rectangle | |||
| int rx = RandomInt(0, w); | |||
| int ry = RandomInt(0, h); | |||
| int rw = RandomInt(0, w - rx); | |||
| int rh = RandomInt(0, h - ry); | |||
| color[0] = 100; | |||
| color[1] = 130; | |||
| color[2] = 150; | |||
| ncnn::draw_rectangle_c3(a, w, h, rx, ry, rw, rh, _color, 3); | |||
| ncnn::draw_rectangle_c3(b, h, w, ry, rx, rh, rw, _color, 3); | |||
| // draw filled rectangle out of image | |||
| color[0] = 144; | |||
| color[1] = 133; | |||
| color[2] = 122; | |||
| ncnn::draw_rectangle_c3(a, w, h, w - 10, -10, 20, 30, _color, -1); | |||
| ncnn::draw_rectangle_c3(b, h, w, -10, w - 10, 30, 20, _color, -1); | |||
| color[0] = 166; | |||
| color[1] = 133; | |||
| color[2] = 122; | |||
| ncnn::draw_rectangle_c3(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 7); | |||
| ncnn::draw_rectangle_c3(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 7); | |||
| // draw rectangle out of image | |||
| color[0] = 44; | |||
| color[1] = 33; | |||
| color[2] = 22; | |||
| ncnn::draw_rectangle_c3(a, w, h, rx + w / 2, ry + h / 2, rw, rh, _color, 1); | |||
| ncnn::draw_rectangle_c3(b, h, w, ry + h / 2, rx + w / 2, rh, rw, _color, 1); | |||
| color[0] = 66; | |||
| color[1] = 44; | |||
| color[2] = 33; | |||
| ncnn::draw_rectangle_c3(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 7); | |||
| ncnn::draw_rectangle_c3(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 7); | |||
| // draw filled circle | |||
| int cx = RandomInt(0, w); | |||
| int cy = RandomInt(0, h); | |||
| int radius = RandomInt(0, std::min(w, h)); | |||
| color[0] = 20; | |||
| color[1] = 120; | |||
| color[2] = 220; | |||
| ncnn::draw_circle_c3(a, w, h, cx, cy, radius, _color, -1); | |||
| ncnn::draw_circle_c3(b, h, w, cy, cx, radius, _color, -1); | |||
| // draw filled circle out of image | |||
| color[0] = 230; | |||
| color[1] = 130; | |||
| color[2] = 110; | |||
| ncnn::draw_circle_c3(a, w, h, 10, -4, 6, _color, -1); | |||
| ncnn::draw_circle_c3(b, h, w, -4, 10, 6, _color, -1); | |||
| // draw circle out of image | |||
| color[0] = 130; | |||
| color[1] = 30; | |||
| color[2] = 230; | |||
| ncnn::draw_circle_c3(a, w, h, cx, cy, radius + std::min(w, h) / 2, _color, 5); | |||
| ncnn::draw_circle_c3(b, h, w, cy, cx, radius + std::min(w, h) / 2, _color, 5); | |||
| // draw line | |||
| int x0 = RandomInt(0, w); | |||
| int y0 = RandomInt(0, h); | |||
| int x1 = RandomInt(0, w); | |||
| int y1 = RandomInt(0, h); | |||
| color[0] = 233; | |||
| color[1] = 233; | |||
| color[2] = 233; | |||
| ncnn::draw_line_c3(a, w, h, x0, y0, x1, y1, _color, 7); | |||
| ncnn::draw_line_c3(b, h, w, y0, x0, y1, x1, _color, 7); | |||
| // draw line out of image | |||
| color[0] = 192; | |||
| color[1] = 192; | |||
| color[2] = 0; | |||
| ncnn::draw_line_c3(a, w, h, x0 - w, y0 - h, x1 + w, y1 + h, _color, 1); | |||
| ncnn::draw_line_c3(b, h, w, y0 - h, x0 - w, y1 + h, x1 + w, _color, 1); | |||
| // transpose b | |||
| ncnn::Mat c(w, h, 3u, 3); | |||
| ncnn::kanna_rotate_c3(b, h, w, c, w, h, 5); | |||
| // draw text | |||
| const char text[] = "Q`~\\=f\nPN\'/<DSA"; | |||
| int tx = RandomInt(0, w / 2); | |||
| int ty = RandomInt(0, h / 2); | |||
| int fontpixelsize = 12; | |||
| color[0] = 0; | |||
| color[1] = 128; | |||
| color[2] = 128; | |||
| ncnn::draw_text_c3(a, w, h, text, tx, ty, fontpixelsize, _color); | |||
| int tw; | |||
| int th; | |||
| ncnn::get_text_drawing_size(text, fontpixelsize, &tw, &th); | |||
| const int len = strlen(text); | |||
| for (int i = 0; i < 6; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c3(c, w, h, ch, tx + tw / 8 * i, ty, fontpixelsize, _color); | |||
| } | |||
| for (int i = 7; i < len; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c3(c, w, h, ch, tx + tw / 8 * (i - 7), ty + th / 2, fontpixelsize, _color); | |||
| } | |||
| // draw text out of image | |||
| fontpixelsize = std::max(w, h) / 2; | |||
| color[0] = 228; | |||
| color[1] = 0; | |||
| color[2] = 128; | |||
| ncnn::draw_text_c3(a, w, h, "qwqwqwq", -13, -15, fontpixelsize, _color); | |||
| ncnn::get_text_drawing_size("qwqwqwq", fontpixelsize, &tw, &th); | |||
| ncnn::draw_text_c3(c, w, h, "qwq", -13, -15, fontpixelsize, _color); | |||
| ncnn::draw_text_c3(c, w, h, "w", -13 + tw / 7 * 3, -15, fontpixelsize, _color); | |||
| ncnn::draw_text_c3(c, w, h, "qwq", -13 + tw / 7 * 4, -15, fontpixelsize, _color); | |||
| if (memcmp(a, c, w * h * 3) != 0) | |||
| { | |||
| fprintf(stderr, "test_mat_pixel_drawing_c3 failed w=%d h=%d\n", w, h); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| static int test_mat_pixel_drawing_c4(int w, int h) | |||
| { | |||
| ncnn::Mat a(w, h, 4u, 4); | |||
| ncnn::Mat b(h, w, 4u, 4); | |||
| int _color = 0; | |||
| unsigned char* color = (unsigned char*)&_color; | |||
| // fill with color | |||
| color[0] = 255; | |||
| color[1] = 255; | |||
| color[2] = 255; | |||
| color[3] = 0; | |||
| ncnn::draw_rectangle_c4(a, w, h, 0, 0, w, h, _color, -1); | |||
| ncnn::draw_rectangle_c4(b, h, w, 0, 0, h, w, _color, -1); | |||
| // draw rectangle | |||
| int rx = RandomInt(0, w); | |||
| int ry = RandomInt(0, h); | |||
| int rw = RandomInt(0, w - rx); | |||
| int rh = RandomInt(0, h - ry); | |||
| color[0] = 100; | |||
| color[1] = 20; | |||
| color[2] = 200; | |||
| color[3] = 100; | |||
| ncnn::draw_rectangle_c4(a, w, h, rx, ry, rw, rh, _color, 3); | |||
| ncnn::draw_rectangle_c4(b, h, w, ry, rx, rh, rw, _color, 3); | |||
| // draw filled rectangle out of image | |||
| color[0] = 144; | |||
| color[1] = 133; | |||
| color[2] = 122; | |||
| color[3] = 30; | |||
| ncnn::draw_rectangle_c4(a, w, h, w - 10, -10, 20, 30, _color, -1); | |||
| ncnn::draw_rectangle_c4(b, h, w, -10, w - 10, 30, 20, _color, -1); | |||
| color[0] = 166; | |||
| color[1] = 133; | |||
| color[2] = 122; | |||
| color[3] = 20; | |||
| ncnn::draw_rectangle_c4(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 7); | |||
| ncnn::draw_rectangle_c4(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 7); | |||
| // draw rectangle out of image | |||
| color[0] = 44; | |||
| color[1] = 144; | |||
| color[2] = 44; | |||
| color[3] = 144; | |||
| ncnn::draw_rectangle_c4(a, w, h, rx + w / 2, ry + h / 2, rw, rh, _color, 1); | |||
| ncnn::draw_rectangle_c4(b, h, w, ry + h / 2, rx + w / 2, rh, rw, _color, 1); | |||
| color[0] = 66; | |||
| color[1] = 44; | |||
| color[2] = 33; | |||
| color[3] = 112; | |||
| ncnn::draw_rectangle_c4(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 7); | |||
| ncnn::draw_rectangle_c4(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 7); | |||
| // draw filled circle | |||
| int cx = RandomInt(0, w); | |||
| int cy = RandomInt(0, h); | |||
| int radius = RandomInt(0, std::min(w, h)); | |||
| color[0] = 10; | |||
| color[1] = 2; | |||
| color[2] = 200; | |||
| color[3] = 20; | |||
| ncnn::draw_circle_c4(a, w, h, cx, cy, radius, _color, -1); | |||
| ncnn::draw_circle_c4(b, h, w, cy, cx, radius, _color, -1); | |||
| // draw filled circle out of image | |||
| color[0] = 230; | |||
| color[1] = 130; | |||
| color[2] = 110; | |||
| color[3] = 5; | |||
| ncnn::draw_circle_c4(a, w, h, 10, -4, 6, _color, -1); | |||
| ncnn::draw_circle_c4(b, h, w, -4, 10, 6, _color, -1); | |||
| // draw circle out of image | |||
| color[0] = 130; | |||
| color[1] = 255; | |||
| color[2] = 130; | |||
| color[3] = 255; | |||
| ncnn::draw_circle_c4(a, w, h, cx, cy, radius + std::min(w, h) / 2, _color, 5); | |||
| ncnn::draw_circle_c4(b, h, w, cy, cx, radius + std::min(w, h) / 2, _color, 5); | |||
| // draw line | |||
| int x0 = RandomInt(0, w); | |||
| int y0 = RandomInt(0, h); | |||
| int x1 = RandomInt(0, w); | |||
| int y1 = RandomInt(0, h); | |||
| color[0] = 233; | |||
| color[1] = 233; | |||
| color[2] = 233; | |||
| color[3] = 233; | |||
| ncnn::draw_line_c4(a, w, h, x0, y0, x1, y1, _color, 7); | |||
| ncnn::draw_line_c4(b, h, w, y0, x0, y1, x1, _color, 7); | |||
| // draw line out of image | |||
| color[0] = 192; | |||
| color[1] = 22; | |||
| color[2] = 1; | |||
| color[3] = 0; | |||
| ncnn::draw_line_c4(a, w, h, x0 - w, y0 - h, x1 + w, y1 + h, _color, 1); | |||
| ncnn::draw_line_c4(b, h, w, y0 - h, x0 - w, y1 + h, x1 + w, _color, 1); | |||
| // transpose b | |||
| ncnn::Mat c(w, h, 4u, 4); | |||
| ncnn::kanna_rotate_c4(b, h, w, c, w, h, 5); | |||
| // draw text | |||
| const char text[] = "!@)\n($ 34\n2]\"M,"; | |||
| int tx = RandomInt(0, w / 2); | |||
| int ty = RandomInt(0, h / 2); | |||
| int fontpixelsize = 23; | |||
| color[0] = 11; | |||
| color[1] = 128; | |||
| color[2] = 12; | |||
| color[3] = 128; | |||
| ncnn::draw_text_c4(a, w, h, text, tx, ty, fontpixelsize, _color); | |||
| int tw; | |||
| int th; | |||
| ncnn::get_text_drawing_size(text, fontpixelsize, &tw, &th); | |||
| const int len = strlen(text); | |||
| for (int i = 0; i < 3; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c4(c, w, h, ch, tx + tw / 5 * i, ty, fontpixelsize, _color); | |||
| } | |||
| for (int i = 4; i < 9; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c4(c, w, h, ch, tx + tw / 5 * (i - 4), ty + th / 3, fontpixelsize, _color); | |||
| } | |||
| for (int i = 10; i < len; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_c4(c, w, h, ch, tx + tw / 5 * (i - 10), ty + th / 3 * 2, fontpixelsize, _color); | |||
| } | |||
| // draw text out of image | |||
| fontpixelsize = std::max(w, h) / 3; | |||
| color[0] = 228; | |||
| color[1] = 0; | |||
| color[2] = 128; | |||
| color[3] = 200; | |||
| ncnn::draw_text_c4(a, w, h, "=_+!//zzzz", -13, -15, fontpixelsize, _color); | |||
| ncnn::get_text_drawing_size("=_+!//zzzz", fontpixelsize, &tw, &th); | |||
| ncnn::draw_text_c4(c, w, h, "=_+", -13, -15, fontpixelsize, _color); | |||
| ncnn::draw_text_c4(c, w, h, "!", -13 + tw / 10 * 3, -15, fontpixelsize, _color); | |||
| ncnn::draw_text_c4(c, w, h, "//zzzz", -13 + tw / 10 * 4, -15, fontpixelsize, _color); | |||
| if (memcmp(a, c, w * h * 4) != 0) | |||
| { | |||
| fprintf(stderr, "test_mat_pixel_drawing_c4 failed w=%d h=%d\n", w, h); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| static int test_mat_pixel_drawing_0() | |||
| { | |||
| return 0 | |||
| || test_mat_pixel_drawing_c1(22, 33) | |||
| || test_mat_pixel_drawing_c2(22, 23) | |||
| || test_mat_pixel_drawing_c3(32, 23) | |||
| || test_mat_pixel_drawing_c4(42, 13) | |||
| || test_mat_pixel_drawing_c1(202, 303) | |||
| || test_mat_pixel_drawing_c2(202, 203) | |||
| || test_mat_pixel_drawing_c3(302, 203) | |||
| || test_mat_pixel_drawing_c4(402, 103); | |||
| } | |||
| static int test_mat_pixel_drawing_yuv420sp(int w, int h) | |||
| { | |||
| ncnn::Mat a(w, h * 3 / 2, 1u, 1); | |||
| ncnn::Mat b(h, w * 3 / 2, 1u, 1); | |||
| int _color = 0; | |||
| unsigned char* color = (unsigned char*)&_color; | |||
| // fill with color | |||
| color[0] = 255; | |||
| color[1] = 255; | |||
| color[2] = 255; | |||
| ncnn::draw_rectangle_yuv420sp(a, w, h, 0, 0, w, h, _color, -1); | |||
| ncnn::draw_rectangle_yuv420sp(b, h, w, 0, 0, h, w, _color, -1); | |||
| // draw rectangle | |||
| int rx = RandomInt2(0, w); | |||
| int ry = RandomInt2(0, h); | |||
| int rw = RandomInt2(0, w - rx); | |||
| int rh = RandomInt2(0, h - ry); | |||
| color[0] = 100; | |||
| color[1] = 20; | |||
| color[2] = 200; | |||
| ncnn::draw_rectangle_yuv420sp(a, w, h, rx, ry, rw, rh, _color, 4); | |||
| ncnn::draw_rectangle_yuv420sp(b, h, w, ry, rx, rh, rw, _color, 4); | |||
| // draw filled rectangle out of image | |||
| color[0] = 144; | |||
| color[1] = 133; | |||
| color[2] = 122; | |||
| ncnn::draw_rectangle_yuv420sp(a, w, h, w - 10, -10, 20, 30, _color, -1); | |||
| ncnn::draw_rectangle_yuv420sp(b, h, w, -10, w - 10, 30, 20, _color, -1); | |||
| color[0] = 166; | |||
| color[1] = 133; | |||
| color[2] = 122; | |||
| ncnn::draw_rectangle_yuv420sp(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 8); | |||
| ncnn::draw_rectangle_yuv420sp(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 8); | |||
| // draw rectangle out of image | |||
| color[0] = 44; | |||
| color[1] = 144; | |||
| color[2] = 44; | |||
| ncnn::draw_rectangle_yuv420sp(a, w, h, rx + w / 2, ry + h / 2, rw, rh, _color, 2); | |||
| ncnn::draw_rectangle_yuv420sp(b, h, w, ry + h / 2, rx + w / 2, rh, rw, _color, 2); | |||
| color[0] = 66; | |||
| color[1] = 44; | |||
| color[2] = 33; | |||
| ncnn::draw_rectangle_yuv420sp(a, w, h, -rw / 2, -rh / 3, rw, rh, _color, 8); | |||
| ncnn::draw_rectangle_yuv420sp(b, h, w, -rh / 3, -rw / 2, rh, rw, _color, 8); | |||
| // draw filled circle | |||
| int cx = RandomInt2(0, w); | |||
| int cy = RandomInt2(0, h); | |||
| int radius = RandomInt2(0, std::min(w, h)); | |||
| color[0] = 10; | |||
| color[1] = 2; | |||
| color[2] = 200; | |||
| ncnn::draw_circle_yuv420sp(a, w, h, cx, cy, radius, _color, -1); | |||
| ncnn::draw_circle_yuv420sp(b, h, w, cy, cx, radius, _color, -1); | |||
| // draw filled circle out of image | |||
| color[0] = 230; | |||
| color[1] = 130; | |||
| color[2] = 110; | |||
| ncnn::draw_circle_yuv420sp(a, w, h, 10, -4, 6, _color, -1); | |||
| ncnn::draw_circle_yuv420sp(b, h, w, -4, 10, 6, _color, -1); | |||
| // draw circle out of image | |||
| color[0] = 130; | |||
| color[1] = 255; | |||
| color[2] = 130; | |||
| ncnn::draw_circle_yuv420sp(a, w, h, cx, cy, radius + std::min(w, h) / 2, _color, 6); | |||
| ncnn::draw_circle_yuv420sp(b, h, w, cy, cx, radius + std::min(w, h) / 2, _color, 6); | |||
| // draw line | |||
| int x0 = RandomInt2(0, w); | |||
| int y0 = RandomInt2(0, h); | |||
| int x1 = RandomInt2(0, w); | |||
| int y1 = RandomInt2(0, h); | |||
| color[0] = 233; | |||
| color[1] = 233; | |||
| color[2] = 233; | |||
| ncnn::draw_line_yuv420sp(a, w, h, x0, y0, x1, y1, _color, 8); | |||
| ncnn::draw_line_yuv420sp(b, h, w, y0, x0, y1, x1, _color, 8); | |||
| // draw line out of image | |||
| color[0] = 192; | |||
| color[1] = 22; | |||
| color[2] = 1; | |||
| ncnn::draw_line_yuv420sp(a, w, h, x0 - w, y0 - h, x1 + w, y1 + h, _color, 2); | |||
| ncnn::draw_line_yuv420sp(b, h, w, y0 - h, x0 - w, y1 + h, x1 + w, _color, 2); | |||
| // transpose b | |||
| ncnn::Mat c(w, h * 3 / 2, 1u, 1); | |||
| ncnn::kanna_rotate_yuv420sp(b, h, w, c, w, h, 5); | |||
| // draw text | |||
| const char text[] = "!@)\n($ 34\n2]\"M,"; | |||
| int tx = RandomInt2(0, w / 2); | |||
| int ty = RandomInt2(0, h / 2); | |||
| int fontpixelsize = 24; | |||
| color[0] = 11; | |||
| color[1] = 128; | |||
| color[2] = 12; | |||
| ncnn::draw_text_yuv420sp(a, w, h, text, tx, ty, fontpixelsize, _color); | |||
| int tw; | |||
| int th; | |||
| ncnn::get_text_drawing_size(text, fontpixelsize, &tw, &th); | |||
| const int len = strlen(text); | |||
| for (int i = 0; i < 3; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_yuv420sp(c, w, h, ch, tx + tw / 5 * i, ty, fontpixelsize, _color); | |||
| } | |||
| for (int i = 4; i < 9; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_yuv420sp(c, w, h, ch, tx + tw / 5 * (i - 4), ty + th / 3, fontpixelsize, _color); | |||
| } | |||
| for (int i = 10; i < len; i++) | |||
| { | |||
| const char ch[2] = {text[i], '\0'}; | |||
| ncnn::draw_text_yuv420sp(c, w, h, ch, tx + tw / 5 * (i - 10), ty + th / 3 * 2, fontpixelsize, _color); | |||
| } | |||
| // draw text out of image | |||
| fontpixelsize = (std::max(w, h) / 3 + 1) / 2 * 2; | |||
| color[0] = 228; | |||
| color[1] = 0; | |||
| color[2] = 128; | |||
| ncnn::draw_text_yuv420sp(a, w, h, "=_+!//zzzz", -14, -12, fontpixelsize, _color); | |||
| ncnn::get_text_drawing_size("=_+!//zzzz", fontpixelsize, &tw, &th); | |||
| ncnn::draw_text_yuv420sp(c, w, h, "=_+", -14, -12, fontpixelsize, _color); | |||
| ncnn::draw_text_yuv420sp(c, w, h, "!", -14 + tw / 10 * 3, -12, fontpixelsize, _color); | |||
| ncnn::draw_text_yuv420sp(c, w, h, "//zzzz", -14 + tw / 10 * 4, -12, fontpixelsize, _color); | |||
| if (memcmp(a, c, w * h * 3 / 2) != 0) | |||
| { | |||
| fprintf(stderr, "test_mat_pixel_drawing_yuv420sp failed w=%d h=%d\n", w, h); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| static int test_mat_pixel_drawing_1() | |||
| { | |||
| return 0 | |||
| || test_mat_pixel_drawing_yuv420sp(10, 10) | |||
| || test_mat_pixel_drawing_yuv420sp(120, 160) | |||
| || test_mat_pixel_drawing_yuv420sp(220, 340); | |||
| } | |||
| int main() | |||
| { | |||
| SRAND(7767517); | |||
| return 0 | |||
| || test_mat_pixel_drawing_0() | |||
| || test_mat_pixel_drawing_1(); | |||
| } | |||