10 void read_raw(std::ifstream& stream, T* out, std::size_t length) {
11 stream.read(reinterpret_cast<std::ifstream::char_type*>(out), length);
15 void write_raw(std::ofstream& stream,
const T* in, std::size_t length) {
16 stream.write(reinterpret_cast<const std::ifstream::char_type*>(in), length);
21 cv::Mat_<cv::Vec3b> import_ycbcr420(std::ifstream& yuv_stream,
int width,
int height) {
22 cv::Size sz(width, height);
23 cv::Size sub_sz(width/2, height/2);
25 cv::Mat_<uchar> y_channel(sz);
26 read_raw(yuv_stream, y_channel.data, width*height);
28 cv::Mat_<uchar> cb_channel(sub_sz);
29 read_raw(yuv_stream, cb_channel.data, width*height/4);
30 cv::resize(cb_channel, cb_channel, sz, 0, 0, cv::INTER_CUBIC);
32 cv::Mat_<uchar> cr_channel(sub_sz);
33 read_raw(yuv_stream, cr_channel.data, width*height/4);
34 cv::resize(cr_channel, cr_channel, sz, 0, 0, cv::INTER_CUBIC);
36 cv::Mat_<cv::Vec3b> ycrcb;
37 std::vector<cv::Mat> src {y_channel, cr_channel, cb_channel};
38 cv::merge(src, ycrcb);
40 cv::Mat_<cv::Vec3b> bgr;
41 cv::cvtColor(ycrcb, bgr, CV_YCrCb2BGR);
46 void export_ycbcr420(std::ofstream& yuv_stream,
const cv::Mat_<cv::Vec3b>& bgr) {
47 cv::Size sz = bgr.size();
48 cv::Size sub_sz(sz.width/2, sz.height/2);
50 cv::Mat_<cv::Vec3b> ycrcb;
51 cv::cvtColor(bgr, ycrcb, CV_BGR2YCrCb);
53 cv::Mat_<uchar> y_channel(sz), cb_channel(sz), cr_channel(sz);
54 std::vector<cv::Mat> dst { y_channel, cr_channel, cb_channel };
55 cv::split(ycrcb, dst);
56 cv::resize(cb_channel, cb_channel, sub_sz, 0, 0, cv::INTER_CUBIC);
57 cv::resize(cr_channel, cr_channel, sub_sz, 0, 0, cv::INTER_CUBIC);
59 write_raw(yuv_stream, y_channel.data, y_channel.cols*y_channel.rows);
60 write_raw(yuv_stream, cb_channel.data, cb_channel.cols*cb_channel.rows);
61 write_raw(yuv_stream, cr_channel.data, cr_channel.cols*cr_channel.rows);
65 cv::Mat_<cv::Vec3b> import_rgb_planar(std::ifstream& yuv_stream,
int width,
int height) {
66 cv::Size sz(width, height);
68 cv::Mat_<uchar> r_channel(sz);
69 read_raw(yuv_stream, r_channel.data, width*height);
71 cv::Mat_<uchar> g_channel(sz);
72 read_raw(yuv_stream, g_channel.data, width*height);
74 cv::Mat_<uchar> b_channel(sz);
75 read_raw(yuv_stream, b_channel.data, width*height);
77 cv::Mat_<cv::Vec3b> bgr(sz);
78 int from_to[] = { 0, 0, 0, 1, 0, 2 };
79 std::vector<cv::Mat> dst { bgr };
80 std::vector<cv::Mat> src { b_channel, g_channel, r_channel };
81 cv::mixChannels(src, dst, from_to, 3);
86 void export_rgb_planar(std::ofstream& yuv_stream,
const cv::Mat_<cv::Vec3b>& bgr) {
87 cv::Size sz = bgr.size();
89 cv::Mat_<uchar> r_channel(sz), g_channel(sz), b_channel(sz);
90 std::vector<cv::Mat> dst { b_channel, g_channel, r_channel };
93 write_raw(yuv_stream, r_channel.data, sz.width*sz.height);
94 write_raw(yuv_stream, g_channel.data, sz.width*sz.height);
95 write_raw(yuv_stream, b_channel.data, sz.width*sz.height);
100 cv::Mat_<cv::Vec3b> import_rgb_interleaved(std::ifstream& yuv_stream,
int width,
int height) {
101 cv::Size sz(width, height);
102 cv::Mat_<uchar> rgb(sz);
103 read_raw(yuv_stream, rgb.data, 3*width*height);
105 cv::cvtColor(rgb, bgr, CV_RGB2BGR);
109 void export_rgb_interleaved(std::ofstream& yuv_stream,
const cv::Mat_<cv::Vec3b>& bgr) {
110 cv::Mat_<cv::Vec3b> rgb;
111 cv::cvtColor(bgr, rgb, CV_BGR2RGB);
112 write_raw(yuv_stream, rgb.data, 3*rgb.cols*rgb.rows);
120 std::ifstream yuv_stream(yuv_filename, std::ios_base::binary);
125 default:
throw std::invalid_argument(
"invalid raw image format");
130 cv::Mat
import_raw_mono(
const std::string& yuv_filename,
int width,
int height,
int bit_depth) {
133 case 8: type = CV_8U;
break;
134 case 16: type = CV_16U;
break;
135 default:
throw std::invalid_argument(
"invalid raw image bit depth");
137 cv::Mat mat(height, width, type);
138 int length = width * height * bit_depth/8;
139 std::ifstream yuv_stream(yuv_filename, std::ios_base::binary);
140 read_raw(yuv_stream, mat.data, length);
146 std::ofstream yuv_stream(yuv_filename, std::ios_base::binary);
151 default:
throw std::invalid_argument(
"invalid raw image format");
156 void export_raw_mono(
const cv::Mat& img,
const std::string& yuv_filename,
int out_bit_depth) {
159 switch(img.depth()) {
160 case CV_8U: in_bit_depth = 8;
break;
161 case CV_16U: in_bit_depth = 16;
break;
162 default:
throw std::invalid_argument(
"invalid input image bit depth");
164 switch(out_bit_depth) {
165 case 8: type = CV_8U;
break;
166 case 16: type = CV_16U;
break;
167 default:
throw std::invalid_argument(
"invalid raw image bit depth");
169 real alpha = std::exp2(out_bit_depth - in_bit_depth);
171 img.convertTo(out_mat, type, alpha);
172 int length = img.cols * img.rows * out_bit_depth/8;
173 std::ofstream yuv_stream(yuv_filename, std::ios_base::binary);
174 write_raw(yuv_stream, out_mat.data, length);
void export_raw_color(const cv::Mat &img, const std::string &yuv_filename, raw_image_format form)
void export_raw_mono(const cv::Mat &img, const std::string &yuv_filename, int out_bit_depth)
cv::Mat import_raw_mono(const std::string &yuv_filename, int width, int height, int bit_depth)
cv::Mat import_raw_color(const std::string &yuv_filename, int width, int height, raw_image_format form)