如何正确保存DLIB物体检测芯片?
How to save DLIB object detection chips properly?
我在保存由 DLIB 的人脸检测模型生成的图像芯片时遇到问题。下面的代码详细说明了我的工作流程。我尝试保存整个图像,如下 d_image
,效果很好。然而,当我尝试保存每个芯片时,我得到了失真的输出(见下面的例子)。我在 Ubuntu 16.04.
上使用 dlib 19.4
// object to store raw image data
cv::Mat rawImage;
// initialize the detector
dlib::frontal_face_detector detector = dlib::get_frontal_face_detector();
// using shape predictor object to create dull_object_detections
dlib::shape_predictor sp;
dlib::deserialize(argv[1]) >> sp;
// for writing out images
int image_id = 1;
while (true){
// retrieve image size
sockt.getData(&image_size, 4, NULL);
if (image_size > 0) {
rawImage.create(1, image_size, CV_8UC1);
// load incoming data from a stream
sockt.getData(rawImage.data, image_size, MSG_WAITALL);
// reshape and correct orientation
dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);
// find the daces!
std::vector<dlib::rectangle> detections = detector(d_image);
if (detections.size() > 0){
// generate additional detection data so we can use
// dlib's extract_image_chips function
std::vector<dlib::full_object_detection> shapes;
for (int idx = 0; idx < detections.size(); idx++){
dlib::full_object_detection shape = sp(d_image, detections[idx]);
shapes.push_back(shape);
}
// write each chip to disk
dlib::array<dlib::array2d<dlib::bgr_pixel>> face_chips;
dlib::extract_image_chips(d_image, dlib::get_face_chip_details(shapes), face_chips);
for (int idx = 0; idx < face_chips.size(); idx++){
std::string fname = argv[2] + std::to_string(image_id) + ".jpg";
dlib::save_jpeg(face_chips[idx], fname);
image_id++;
}
}
保存筹码示例:
编辑:向 utils::process_frame
添加了评论。此函数接受 1xN 数组并使用 OpenCV
解码为 JPEG
您使用的图像格式有问题:
这是 OpenCV 的灰度(1 通道)图像
rawImage.create(1, image_size, CV_8UC1);
这是 BGR(3 通道)图像
dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);
如果图像的通道数不正确,Dlib 应该会抛出异常,但在您的情况下不会抛出异常。这意味着在 utils::process_frame(rawImage)
中的某处,图像格式首先更改为 3 通道-检查图像格式
并且此构造代码 rawImage.create(1, image_size, CV_8UC1);
构造 1 行和 image_size 列图像。
图片大小和格式不正确
另请注意,dlib 不会将图像数据复制到 dlib::cv_image<dlib::bgr_pixel> d_image
并且 rawImage
应在处理完成之前由其他线程保持不变
无论如何,你可以调用dlib::toMat
,获取OpenCV Mat并用OpenCV函数保存它
更新:
这里还有一件事:
dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);
看起来像 utils::process_frame returns 一些临时对象,在 d_image 构造后被销毁。 d_image 不保留返回的数据,它可能会丢失
所以我建议您像这样更改代码:
cv::Mat uncompressed;
tils::process_frame(rawImage, uncompressed);
dlib::cv_image<dlib::bgr_pixel> d_image(uncompressed);;
其中 process_frame 应该引用 cv::Mat 并将其输出保存到其中
我在保存由 DLIB 的人脸检测模型生成的图像芯片时遇到问题。下面的代码详细说明了我的工作流程。我尝试保存整个图像,如下 d_image
,效果很好。然而,当我尝试保存每个芯片时,我得到了失真的输出(见下面的例子)。我在 Ubuntu 16.04.
// object to store raw image data
cv::Mat rawImage;
// initialize the detector
dlib::frontal_face_detector detector = dlib::get_frontal_face_detector();
// using shape predictor object to create dull_object_detections
dlib::shape_predictor sp;
dlib::deserialize(argv[1]) >> sp;
// for writing out images
int image_id = 1;
while (true){
// retrieve image size
sockt.getData(&image_size, 4, NULL);
if (image_size > 0) {
rawImage.create(1, image_size, CV_8UC1);
// load incoming data from a stream
sockt.getData(rawImage.data, image_size, MSG_WAITALL);
// reshape and correct orientation
dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);
// find the daces!
std::vector<dlib::rectangle> detections = detector(d_image);
if (detections.size() > 0){
// generate additional detection data so we can use
// dlib's extract_image_chips function
std::vector<dlib::full_object_detection> shapes;
for (int idx = 0; idx < detections.size(); idx++){
dlib::full_object_detection shape = sp(d_image, detections[idx]);
shapes.push_back(shape);
}
// write each chip to disk
dlib::array<dlib::array2d<dlib::bgr_pixel>> face_chips;
dlib::extract_image_chips(d_image, dlib::get_face_chip_details(shapes), face_chips);
for (int idx = 0; idx < face_chips.size(); idx++){
std::string fname = argv[2] + std::to_string(image_id) + ".jpg";
dlib::save_jpeg(face_chips[idx], fname);
image_id++;
}
}
保存筹码示例:
编辑:向 utils::process_frame
添加了评论。此函数接受 1xN 数组并使用 OpenCV
您使用的图像格式有问题:
这是 OpenCV 的灰度(1 通道)图像
rawImage.create(1, image_size, CV_8UC1);
这是 BGR(3 通道)图像
dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);
如果图像的通道数不正确,Dlib 应该会抛出异常,但在您的情况下不会抛出异常。这意味着在 utils::process_frame(rawImage)
中的某处,图像格式首先更改为 3 通道-检查图像格式
并且此构造代码 rawImage.create(1, image_size, CV_8UC1);
构造 1 行和 image_size 列图像。
图片大小和格式不正确
另请注意,dlib 不会将图像数据复制到 dlib::cv_image<dlib::bgr_pixel> d_image
并且 rawImage
应在处理完成之前由其他线程保持不变
无论如何,你可以调用dlib::toMat
,获取OpenCV Mat并用OpenCV函数保存它
更新: 这里还有一件事:
dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);
看起来像 utils::process_frame returns 一些临时对象,在 d_image 构造后被销毁。 d_image 不保留返回的数据,它可能会丢失 所以我建议您像这样更改代码:
cv::Mat uncompressed;
tils::process_frame(rawImage, uncompressed);
dlib::cv_image<dlib::bgr_pixel> d_image(uncompressed);;
其中 process_frame 应该引用 cv::Mat 并将其输出保存到其中