使用 boost::gil 编写 jpeg 文件
Writing a jpeg file with boost::gil
我正在尝试读取一个 jpeg 文件,进行一些简单的转换并使用 boost::gil 库将其写出。
现在我被卡住了,因为即使读出一个文件,提取非白点(它只包含红色和白色的点)并将它们写入另一个文件也会产生完全出乎意料的结果。我希望图片是一样的,但结果是这样的:
这是输入图片。
这是输出图片:
我是这样读非白坐标的:
vector<Point2D> points;
//load points from file
rgb8_image_t img;
jpeg_read_image(in_file_path, img );
assert( 2 == img._view.num_dimensions );
const auto dimensions = img._view.dimensions();
assert( 2 == dimensions.num_dimensions );
row_width = dimensions.x;
col_height = dimensions.y;
size_t white_cnt = 0;
size_t non_white_cnt = 0;
for ( uint32_t x = 0; x < dimensions.x; ++x ){
for ( uint32_t y = 0; y < dimensions.y; ++y ){
const rgb8_pixel_t& pix = const_view(img)( rgb8_image_t::point_t(x,y) );
if ( !is_white(pix) ){
points.push_back( Point2D {x,y} );
}
}
}
这就是相同点的写法
rgb8_image_t img(row_width,col_heigth);
rgb8_pixel_t white(255,255,255);
rgb8_pixel_t red(255,0,0);
rgb8_pixel_t blue(0,0,255);
fill_pixels( view(img), white );
cout << "printing " << points.size() << "points" << std::endl;
for ( Point2D p : points ){
const auto x = p[0];
const auto y = p[1];
cout << x <<"," << y << endl;
view(img)( rgb8_image_t::point_t( x,y ) ) = red;
}
jpeg_write_view( out_file_path, const_view(img));
为了完整性,这是 is_white 检查:
bool is_white( const boost::gil::rgb8_pixel_t& pix ){
const auto r = boost::gil::at_c<0>(pix);
const auto g = boost::gil::at_c<1>(pix);
const auto b = boost::gil::at_c<2>(pix);
constexpr auto MAX_VAL = std::numeric_limits<decltype(r)>::max();
return ( MAX_VAL == r ) && ( MAX_VAL == g ) && ( MAX_VAL == b );
}
知道我做错了什么吗?
谢谢
由于源数据中的 JPEG 伪像,您有许多实际上不是红色的非白色像素:
您需要将颜色与阈值进行比较。我决定对于您当前的数据,在灰度视图中检测非白度会更有效,因此整个程序有效地变为:
gil::transform_pixels(
const_view(input),
view(output),
[](auto& pix) { return pix<200? blue : white; });
这是修改后的片段:
#include <boost/gil.hpp>
#include <boost/gil/color_convert.hpp>
#include <boost/gil/extension/io/jpeg.hpp>
#include <boost/gil/io/io.hpp>
#include <iostream>
namespace gil = boost::gil;
int main() {
static const gil::rgb8_pixel_t
white(255, 255, 255),
red(255, 0, 0),
blue(0, 0, 255);
// load points from file
gil::gray8_image_t input;
read_and_convert_image("input.jpg", input,
gil::image_read_settings<gil::jpeg_tag>{});
auto dimensions = input._view.dimensions();
gil::rgb8_image_t output(dimensions.x, dimensions.y, white);
gil::transform_pixels(
const_view(input),
view(output),
[](auto& pix) { return pix<200? blue : white; });
write_view("output.jpg", const_view(output), gil::jpeg_tag());
}
备注
- 有几个简化项
- 我正在使用新的 IO 接口
- 我在灰色通道 (200) 中选择了一个随机阈值来检测白度,这是我的第一个阈值,它似乎效果很好,但你可能想根据你的输入调整它
- 我将输出像素颜色更改为蓝色 "prove" 我不只是显示输入图像:)
这里的输入和输出交替:
我正在尝试读取一个 jpeg 文件,进行一些简单的转换并使用 boost::gil 库将其写出。 现在我被卡住了,因为即使读出一个文件,提取非白点(它只包含红色和白色的点)并将它们写入另一个文件也会产生完全出乎意料的结果。我希望图片是一样的,但结果是这样的:
这是输入图片。
这是输出图片:
我是这样读非白坐标的:
vector<Point2D> points;
//load points from file
rgb8_image_t img;
jpeg_read_image(in_file_path, img );
assert( 2 == img._view.num_dimensions );
const auto dimensions = img._view.dimensions();
assert( 2 == dimensions.num_dimensions );
row_width = dimensions.x;
col_height = dimensions.y;
size_t white_cnt = 0;
size_t non_white_cnt = 0;
for ( uint32_t x = 0; x < dimensions.x; ++x ){
for ( uint32_t y = 0; y < dimensions.y; ++y ){
const rgb8_pixel_t& pix = const_view(img)( rgb8_image_t::point_t(x,y) );
if ( !is_white(pix) ){
points.push_back( Point2D {x,y} );
}
}
}
这就是相同点的写法
rgb8_image_t img(row_width,col_heigth);
rgb8_pixel_t white(255,255,255);
rgb8_pixel_t red(255,0,0);
rgb8_pixel_t blue(0,0,255);
fill_pixels( view(img), white );
cout << "printing " << points.size() << "points" << std::endl;
for ( Point2D p : points ){
const auto x = p[0];
const auto y = p[1];
cout << x <<"," << y << endl;
view(img)( rgb8_image_t::point_t( x,y ) ) = red;
}
jpeg_write_view( out_file_path, const_view(img));
为了完整性,这是 is_white 检查:
bool is_white( const boost::gil::rgb8_pixel_t& pix ){
const auto r = boost::gil::at_c<0>(pix);
const auto g = boost::gil::at_c<1>(pix);
const auto b = boost::gil::at_c<2>(pix);
constexpr auto MAX_VAL = std::numeric_limits<decltype(r)>::max();
return ( MAX_VAL == r ) && ( MAX_VAL == g ) && ( MAX_VAL == b );
}
知道我做错了什么吗?
谢谢
由于源数据中的 JPEG 伪像,您有许多实际上不是红色的非白色像素:
您需要将颜色与阈值进行比较。我决定对于您当前的数据,在灰度视图中检测非白度会更有效,因此整个程序有效地变为:
gil::transform_pixels(
const_view(input),
view(output),
[](auto& pix) { return pix<200? blue : white; });
这是修改后的片段:
#include <boost/gil.hpp>
#include <boost/gil/color_convert.hpp>
#include <boost/gil/extension/io/jpeg.hpp>
#include <boost/gil/io/io.hpp>
#include <iostream>
namespace gil = boost::gil;
int main() {
static const gil::rgb8_pixel_t
white(255, 255, 255),
red(255, 0, 0),
blue(0, 0, 255);
// load points from file
gil::gray8_image_t input;
read_and_convert_image("input.jpg", input,
gil::image_read_settings<gil::jpeg_tag>{});
auto dimensions = input._view.dimensions();
gil::rgb8_image_t output(dimensions.x, dimensions.y, white);
gil::transform_pixels(
const_view(input),
view(output),
[](auto& pix) { return pix<200? blue : white; });
write_view("output.jpg", const_view(output), gil::jpeg_tag());
}
备注
- 有几个简化项
- 我正在使用新的 IO 接口
- 我在灰色通道 (200) 中选择了一个随机阈值来检测白度,这是我的第一个阈值,它似乎效果很好,但你可能想根据你的输入调整它
- 我将输出像素颜色更改为蓝色 "prove" 我不只是显示输入图像:)
这里的输入和输出交替: