Implementation:Tencent Ncnn Imreadwrite
| Knowledge Sources | |
|---|---|
| Domains | Image_IO, Quantization_Tools |
| Last Updated | 2026-02-09 19:00 GMT |
Overview
Provides OpenCV-compatible cv::imread and cv::imwrite functions using stb_image/stb_image_write as the backend, so the quantization tools can load and save images without requiring OpenCV.
Description
The implementation spans two files: imreadwrite.h (header, 189 lines) and imreadwrite.cpp (implementation, 201 lines).
The header declares a minimal OpenCV-compatible cv::Mat class with:
- Reference-counted pixel data storage using NCNN_XADD for atomic reference count operations
- Copy and assignment semantics with proper reference counting
- create, clone, release, empty, type, and total methods
- OpenCV-style type macros: CV_8UC1 (1 channel), CV_8UC3 (3 channels), CV_8UC4 (4 channels)
- Read mode enums: IMREAD_UNCHANGED (-1), IMREAD_GRAYSCALE (0), IMREAD_COLOR (1)
- Write flags: IMWRITE_JPEG_QUALITY for JPEG quality control
The implementation file uses stb_image (with STB_IMAGE_IMPLEMENTATION) for reading and stb_image_write (with STB_IMAGE_WRITE_IMPLEMENTATION) for writing, configured to support only JPEG, PNG, BMP, and PNM formats.
cv::imread calls stbi_load with the appropriate desired channel count based on the read mode flag, copies the pixel data into a cv::Mat, and frees the stb buffer. It handles 1-channel (grayscale), 3-channel (color), and 4-channel (alpha) images.
cv::imwrite dispatches to stbi_write_jpg, stbi_write_png, or stbi_write_bmp based on the output file extension. For JPEG, it respects the IMWRITE_JPEG_QUALITY parameter (defaulting to 90). For PNG, it uses a stride of width times channels.
Usage
This is a lightweight fallback image I/O implementation that eliminates the OpenCV dependency for the quantization calibration tool (ncnn2table) when neither OpenCV nor simpleocv is available. It provides the minimum cv::Mat API surface needed to load calibration images.
Code Reference
Source Location
- Repository: Tencent_Ncnn
- Header: tools/quantize/imreadwrite.h
- Implementation: tools/quantize/imreadwrite.cpp
- Lines: imreadwrite.h: 1-189, imreadwrite.cpp: 1-201
Signature
namespace cv {
#define CV_8UC1 1
#define CV_8UC3 3
#define CV_8UC4 4
struct Mat {
Mat();
Mat(int _rows, int _cols, int flags);
Mat(const Mat& m);
Mat(int _rows, int _cols, int flags, void* _data);
~Mat();
Mat& operator=(const Mat& m);
void create(int _rows, int _cols, int flags);
void release();
Mat clone() const;
bool empty() const;
int type() const;
size_t total() const;
uchar* data;
int* refcount;
int rows;
int cols;
int c;
};
enum ImreadModes {
IMREAD_UNCHANGED = -1,
IMREAD_GRAYSCALE = 0,
IMREAD_COLOR = 1
};
Mat imread(const std::string& path, int flags = IMREAD_COLOR);
enum ImwriteFlags {
IMWRITE_JPEG_QUALITY = 1
};
bool imwrite(const std::string& path, const Mat& m,
const std::vector<int>& params = std::vector<int>());
} // namespace cv
Import
// Library component - included by quantization tools
#include "imreadwrite.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| path | std::string | Yes | File path for the image to read or write |
| flags | int (ImreadModes) | No | Read mode: IMREAD_UNCHANGED (-1), IMREAD_GRAYSCALE (0), IMREAD_COLOR (1, default) |
| params | std::vector<int> | No | Write parameters (e.g., IMWRITE_JPEG_QUALITY followed by quality value) |
Outputs
| Name | Type | Description |
|---|---|---|
| Mat (imread) | cv::Mat | Image data with pixel buffer, dimensions (rows, cols), and channel count |
| success (imwrite) | bool | Whether the image was successfully written to disk |
Usage Examples
Reading an Image
#include "imreadwrite.h"
// Read as color (3 channels)
cv::Mat img = cv::imread("calibration_image.jpg", cv::IMREAD_COLOR);
if (!img.empty()) {
// img.rows, img.cols, img.c are set
// img.data points to pixel buffer
}
// Read as grayscale
cv::Mat gray = cv::imread("image.png", cv::IMREAD_GRAYSCALE);
Writing an Image
#include "imreadwrite.h"
// Write as PNG
cv::imwrite("output.png", img);
// Write as JPEG with quality 95
std::vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 95};
cv::imwrite("output.jpg", img, params);