|
18 | 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
19 | 19 | // THE SOFTWARE. |
20 | 20 |
|
| 21 | + |
21 | 22 | #include <nlohmann/json.hpp> |
| 23 | +#include <opencv2/imgcodecs.hpp> |
22 | 24 | #include <shisen_cpp/camera/node/camera_node.hpp> |
| 25 | +#include <jitsuyo/config.hpp> |
23 | 26 |
|
| 27 | +#include <chrono> |
24 | 28 | #include <fstream> |
25 | 29 | #include <memory> |
| 30 | +#include <sstream> |
26 | 31 | #include <string> |
27 | 32 |
|
28 | 33 | namespace shisen_cpp::camera |
@@ -64,6 +69,32 @@ void CameraNode::on_camera_config(int width, int height) |
64 | 69 | camera_config_publisher->publish(camera_config_provider->get_camera_config()); |
65 | 70 | } |
66 | 71 |
|
| 72 | +void CameraNode::save_image(cv::Mat mat) |
| 73 | +{ |
| 74 | + if (!std::filesystem::exists("image")) { |
| 75 | + if (!std::filesystem::create_directory("image")) { |
| 76 | + RCLCPP_ERROR(node->get_logger(), "Error creating `image` directory!"); |
| 77 | + return; |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + auto now = std::chrono::system_clock::now(); |
| 82 | + std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); |
| 83 | + auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000; |
| 84 | + |
| 85 | + std::stringstream ss; |
| 86 | + ss << std::put_time(std::localtime(&now_time_t), "%Y-%m-%d_%H-%M-%S"); |
| 87 | + ss << '-' << std::setfill('0') << std::setw(3) << now_ms.count(); |
| 88 | + std::string timestamp = ss.str(); |
| 89 | + |
| 90 | + std::string filename = "image/" + timestamp + ".jpg"; |
| 91 | + |
| 92 | + bool result = cv::imwrite(filename, mat); |
| 93 | + if (!result) { |
| 94 | + RCLCPP_ERROR(node->get_logger(), "Failed to save image!"); |
| 95 | + } |
| 96 | +} |
| 97 | + |
67 | 98 | cv::Mat CameraNode::get_mat() |
68 | 99 | { |
69 | 100 | update(); |
@@ -161,12 +192,10 @@ CaptureSetting CameraNode::on_configure_capture_setting( |
161 | 192 | } |
162 | 193 |
|
163 | 194 | if (new_capture_setting.temperature.is_not_empty()) { |
164 | | - video_capture->set(cv::CAP_PROP_AUTO_WB, 0); |
165 | 195 | video_capture->set(cv::CAP_PROP_WB_TEMPERATURE, new_capture_setting.temperature); |
166 | 196 | } |
167 | 197 |
|
168 | 198 | if (new_capture_setting.exposure.is_not_empty()) { |
169 | | - video_capture->set(cv::CAP_PROP_AUTO_EXPOSURE, 1); |
170 | 199 | video_capture->set(cv::CAP_PROP_EXPOSURE, new_capture_setting.exposure); |
171 | 200 | } |
172 | 201 |
|
@@ -195,38 +224,38 @@ void CameraNode::configure_capture_setting(const CaptureSetting & capture_settin |
195 | 224 |
|
196 | 225 | void CameraNode::load_configuration(const std::string & path) |
197 | 226 | { |
198 | | - std::string ss = path + "capture_settings.json"; |
199 | | - |
200 | | - std::ifstream input(ss, std::ifstream::in); |
201 | | - if (!input.is_open()) { |
202 | | - throw std::runtime_error("Unable to open `" + ss + "`!"); |
| 227 | + nlohmann::json config; |
| 228 | + if (!jitsuyo::load_config(path, "capture_settings.json", config)) { |
| 229 | + throw std::runtime_error("Unable to open `" + path + "capture_settings.json`!"); |
203 | 230 | } |
204 | 231 |
|
205 | | - nlohmann::json config = nlohmann::json::parse(input); |
206 | | - |
207 | 232 | CaptureSetting capture_setting; |
208 | 233 |
|
209 | | - // Get all config |
210 | | - for (auto & item : config.items()) { |
211 | | - try { |
212 | | - if (item.key() == "brightness") { |
213 | | - capture_setting.brightness.set(item.value()); |
214 | | - } else if (item.key() == "contrast") { |
215 | | - capture_setting.contrast.set(item.value()); |
216 | | - } else if (item.key() == "saturation") { |
217 | | - capture_setting.saturation.set(item.value()); |
218 | | - } else if (item.key() == "temperature") { |
219 | | - capture_setting.temperature.set(item.value()); |
220 | | - } else if (item.key() == "exposure") { |
221 | | - capture_setting.exposure.set(item.value()); |
222 | | - } else if (item.key() == "gain") { |
223 | | - capture_setting.gain.set(item.value()); |
224 | | - } |
225 | | - } catch (nlohmann::json::parse_error & ex) { |
226 | | - throw std::runtime_error("Parse error at byte `" + std::to_string(ex.byte) + "`!"); |
227 | | - } |
| 234 | + int setting_brightness; |
| 235 | + int setting_contrast; |
| 236 | + int setting_saturation; |
| 237 | + int setting_temperature; |
| 238 | + int setting_exposure; |
| 239 | + int setting_gain; |
| 240 | + |
| 241 | + if (!jitsuyo::assign_val(config, "brightness", setting_brightness) || |
| 242 | + !jitsuyo::assign_val(config, "contrast", setting_contrast) || |
| 243 | + !jitsuyo::assign_val(config, "saturation", setting_saturation) || |
| 244 | + !jitsuyo::assign_val(config, "temperature", setting_temperature) || |
| 245 | + !jitsuyo::assign_val(config, "exposure", setting_exposure) || |
| 246 | + !jitsuyo::assign_val(config, "gain", setting_gain)) |
| 247 | + { |
| 248 | + std::cout << "Error found at section `capture_settings`" << std::endl; |
| 249 | + throw std::runtime_error("Failed to load config file `" + path + "capture_settings.json`"); |
228 | 250 | } |
229 | 251 |
|
| 252 | + capture_setting.brightness.set(setting_brightness); |
| 253 | + capture_setting.contrast.set(setting_contrast); |
| 254 | + capture_setting.saturation.set(setting_saturation); |
| 255 | + capture_setting.temperature.set(setting_temperature); |
| 256 | + capture_setting.exposure.set(setting_exposure); |
| 257 | + capture_setting.gain.set(setting_gain); |
| 258 | + |
230 | 259 | configure_capture_setting(capture_setting); |
231 | 260 | } |
232 | 261 |
|
|
0 commit comments