diff --git a/cmake/Depthai/DepthaiDeviceSideConfig.cmake b/cmake/Depthai/DepthaiDeviceSideConfig.cmake index 614e12672..14bf0632a 100644 --- a/cmake/Depthai/DepthaiDeviceSideConfig.cmake +++ b/cmake/Depthai/DepthaiDeviceSideConfig.cmake @@ -2,7 +2,7 @@ set(DEPTHAI_DEVICE_SIDE_MATURITY "snapshot") # "full commit hash of device side binary" -set(DEPTHAI_DEVICE_SIDE_COMMIT "4f9c559d826a1238f91f5b72c5178c4a3be76c2b") +set(DEPTHAI_DEVICE_SIDE_COMMIT "d49ac887074adf18024c21e33ce071ea48b0c014") # "version if applicable" set(DEPTHAI_DEVICE_SIDE_VERSION "") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 89c35f684..2157a0d38 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -74,8 +74,9 @@ dai_add_example(mjpeg_encoding src/mjpeg_encoding_example.cpp) # StereoDepth example dai_add_example(stereo src/stereo_example.cpp) -# Image Manip node example +# Image Manip node examples dai_add_example(image_manip src/image_manip_example.cpp) +dai_add_example(image_manip_warp src/image_manip_warp_example.cpp) # Color Camera config example dai_add_example(color_camera_control src/color_camera_control_example.cpp) diff --git a/examples/src/color_camera_control_example.cpp b/examples/src/color_camera_control_example.cpp index e5077c008..ed3de69da 100644 --- a/examples/src/color_camera_control_example.cpp +++ b/examples/src/color_camera_control_example.cpp @@ -1,5 +1,15 @@ -// This example shows usage of Camera Control message as well as ColorCamera configInput to change crop x and y - +/** + * This example shows usage of Camera Control message as well as ColorCamera configInput to change crop x and y + * Uses 'WASD' controls to move the crop window, 'C' to capture a still image, 'T' to trigger autofocus, 'IOKL,.' + * for manual exposure/focus: + * Control: key[dec/inc] min..max + * exposure time: I O 1..33000 [us] + * sensitivity iso: K L 100..1600 + * focus: , . 0..255 [far..near] + * To go back to auto controls: + * 'E' - autoexposure + * 'F' - autofocus (continuous) + */ #include #include @@ -12,6 +22,15 @@ // Step size ('W','A','S','D' controls) static constexpr int STEP_SIZE = 16; +// Manual exposure/focus set step +static constexpr int EXP_STEP = 500; // us +static constexpr int ISO_STEP = 50; +static constexpr int LENS_STEP = 3; + +static int clamp(int num, int v0, int v1) { + return std::max(v0, std::min(num, v1)); +} + int main(){ dai::Pipeline pipeline; @@ -67,8 +86,18 @@ int main(){ float crop_x = 0; float crop_y = 0; - float prev_crop_x = crop_x; - float prev_crop_y = crop_y; + // Defaults and limits for manual focus/exposure controls + int lens_pos = 150; + int lens_min = 0; + int lens_max = 255; + + int exp_time = 20000; + int exp_min = 1; + int exp_max = 33000; + + int sens_iso = 800; + int sens_min = 100; + int sens_max = 1600; while(true){ @@ -105,35 +134,64 @@ int main(){ dai::CameraControl ctrl; ctrl.setCaptureStill(true); controlQueue->send(ctrl); - } else if(key == 'a'){ - crop_x -= (max_crop_x / colorCam->getResolutionWidth()) * STEP_SIZE; - if (crop_x < 0) crop_x = max_crop_x; - } else if(key == 'd'){ - crop_x += (max_crop_x / colorCam->getResolutionWidth()) * STEP_SIZE; - if (crop_x > max_crop_x) crop_x = 0.0f; - } else if(key == 'w'){ - crop_y -= (max_crop_y / colorCam->getResolutionHeight()) * STEP_SIZE; - if (crop_y < 0) crop_y = max_crop_y; - } else if(key == 's'){ - crop_y += (max_crop_y / colorCam->getResolutionHeight()) * STEP_SIZE; - if (crop_y > max_crop_y) crop_y = 0.0f; - } - + } else if (key == 't') { + printf("Autofocus trigger (and disable continuous)\n"); + dai::CameraControl ctrl; + ctrl.setAutoFocusMode(dai::CameraControl::AutoFocusMode::AUTO); + ctrl.setAutoFocusTrigger(); + controlQueue->send(ctrl); + } else if (key == 'f') { + printf("Autofocus enable, continuous\n"); + dai::CameraControl ctrl; + ctrl.setAutoFocusMode(dai::CameraControl::AutoFocusMode::CONTINUOUS_VIDEO); + controlQueue->send(ctrl); + } else if (key == 'e') { + printf("Autoexposure enable\n"); + dai::CameraControl ctrl; + ctrl.setAutoExposureEnable(); + controlQueue->send(ctrl); + } else if (key == ',' || key == '.') { + if (key == ',') lens_pos -= LENS_STEP; + if (key == '.') lens_pos += LENS_STEP; + lens_pos = clamp(lens_pos, lens_min, lens_max); + printf("Setting manual focus, lens position: %d\n", lens_pos); + dai::CameraControl ctrl; + ctrl.setManualFocus(lens_pos); + controlQueue->send(ctrl); + } else if (key == 'i' || key == 'o' || key == 'k' || key == 'l') { + if (key == 'i') exp_time -= EXP_STEP; + if (key == 'o') exp_time += EXP_STEP; + if (key == 'k') sens_iso -= ISO_STEP; + if (key == 'l') sens_iso += ISO_STEP; + exp_time = clamp(exp_time, exp_min, exp_max); + sens_iso = clamp(sens_iso, sens_min, sens_max); + printf("Setting manual exposure, time %d us, iso %d\n", exp_time, sens_iso); + dai::CameraControl ctrl; + ctrl.setManualExposure(exp_time, sens_iso); + controlQueue->send(ctrl); + } else if (key == 'w' || key == 'a' || key == 's' || key == 'd') { + if(key == 'a'){ + crop_x -= (max_crop_x / colorCam->getResolutionWidth()) * STEP_SIZE; + if (crop_x < 0) crop_x = max_crop_x; + } else if(key == 'd'){ + crop_x += (max_crop_x / colorCam->getResolutionWidth()) * STEP_SIZE; + if (crop_x > max_crop_x) crop_x = 0.0f; + } else if(key == 'w'){ + crop_y -= (max_crop_y / colorCam->getResolutionHeight()) * STEP_SIZE; + if (crop_y < 0) crop_y = max_crop_y; + } else if(key == 's'){ + crop_y += (max_crop_y / colorCam->getResolutionHeight()) * STEP_SIZE; + if (crop_y > max_crop_y) crop_y = 0.0f; + } - // if crop changed - if(prev_crop_x != crop_x || prev_crop_y != crop_y){ // Send new cfg to camera dai::ImageManipConfig cfg; cfg.setCropRect(crop_x, crop_y, 0, 0); configQueue->send(cfg); printf("Sending new crop - x: %f, y: %f\n", crop_x, crop_y); } - - // set prev crop - prev_crop_x = crop_x; - prev_crop_y = crop_y; } -} \ No newline at end of file +} diff --git a/examples/src/image_manip_example.cpp b/examples/src/image_manip_example.cpp index 415225081..b06710f46 100644 --- a/examples/src/image_manip_example.cpp +++ b/examples/src/image_manip_example.cpp @@ -33,11 +33,11 @@ int main(){ colorCam->setColorOrder(dai::ColorCameraProperties::ColorOrder::BGR); // Create a center crop image manipulation - imageManip->setCenterCrop(0.7f); - imageManip->setResizeThumbnail(300, 400); + imageManip->initialConfig.setCenterCrop(0.7f); + imageManip->initialConfig.setResizeThumbnail(300, 400); // Second image manipulator - Create a off center crop - imageManip2->setCropRect(0.1, 0.1, 0.3, 0.3); + imageManip2->initialConfig.setCropRect(0.1, 0.1, 0.3, 0.3); imageManip2->setWaitForConfigInput(true); @@ -108,4 +108,4 @@ int main(){ } -} \ No newline at end of file +} diff --git a/examples/src/image_manip_warp_example.cpp b/examples/src/image_manip_warp_example.cpp new file mode 100644 index 000000000..3d77ece3f --- /dev/null +++ b/examples/src/image_manip_warp_example.cpp @@ -0,0 +1,172 @@ +#include +#include + +#include "utility.hpp" + +#include "depthai/depthai.hpp" + +struct warpFourPointTest { + std::vector points; + bool normalizedCoords; + const char *description; +}; + +#define ROTATE_RATE_MAX 5.0 +#define ROTATE_RATE_INC 0.1 +#define KEY_ROTATE_DECR 'z' +#define KEY_ROTATE_INCR 'x' + +#define RESIZE_MAX_W 800 +#define RESIZE_MAX_H 600 +#define RESIZE_FACTOR_MAX 5 +#define KEY_RESIZE_INC 'v' + +/* The crop points are specified in clockwise order, + * with first point mapped to output top-left, as: + * P0 -> P1 + * ^ v + * P3 <- P2 + */ +#define P0 {0, 0} // top-left +#define P1 {1, 0} // top-right +#define P2 {1, 1} // bottom-right +#define P3 {0, 1} // bottom-left +std::vector warpList = { + //{{{ 0, 0},{ 1, 0},{ 1, 1},{ 0, 1}}, true, "passthrough"}, + //{{{ 0, 0},{639, 0},{639,479},{ 0,479}}, false,"passthrough (pixels)"}, + {{P0, P1, P2, P3}, true, "1.passthrough"}, + {{P3, P0, P1, P2}, true, "2.rotate 90"}, + {{P2, P3, P0, P1}, true, "3.rotate 180"}, + {{P1, P2, P3, P0}, true, "4.rotate 270"}, + {{P1, P0, P3, P2}, true, "5.horizontal mirror"}, + {{P3, P2, P1, P0}, true, "6.vertical flip"}, + {{{-0.1,-0.1},{1.1,-0.1},{1.1,1.1},{-0.1,1.1}}, true, "7.add black borders"}, + {{{-0.3, 0},{1, 0},{1.3, 1},{0, 1}}, true, "8.parallelogram transform"}, + {{{-0.2, 0},{1.8, 0},{1, 1},{0, 1}}, true, "9.trapezoid transform"}, +}; +#define KEY_WARP_TEST_CYCLE 'c' + +void printControls() { + printf("\n=== Controls:\n"); + printf(" %c -rotated rectangle crop, decrease rate\n", KEY_ROTATE_DECR); + printf(" %c -rotated rectangle crop, increase rate\n", KEY_ROTATE_INCR); + printf(" %c -warp 4-point transform, cycle through modes\n", KEY_WARP_TEST_CYCLE); + printf(" %c -resize cropped region, or disable resize\n", KEY_RESIZE_INC); + printf(" h -print controls (help)\n"); +} + +int main(){ + dai::Pipeline pipeline; + + auto colorCam = pipeline.create(); + auto camOut = pipeline.create(); + auto manip = pipeline.create(); + auto manipCfg = pipeline.create(); + auto manipOut = pipeline.create(); + + camOut->setStreamName("preview"); + manipOut->setStreamName("manip"); + manipCfg->setStreamName("manipCfg"); + + colorCam->setPreviewSize(640, 480); + colorCam->setResolution(dai::ColorCameraProperties::SensorResolution::THE_1080_P); + colorCam->setInterleaved(false); + colorCam->setColorOrder(dai::ColorCameraProperties::ColorOrder::BGR); + manip->setMaxOutputFrameSize(2000*1500*3); + + /* Link nodes: CAM --> XLINK(preview) + * \--> manip -> XLINK(manipOut) + * manipCfg ---/ + */ + colorCam->preview.link(camOut->input); + colorCam->preview.link(manip->inputImage); + manip->out.link(manipOut->input); + manipCfg->out.link(manip->inputConfig); + + // Connect to device and start pipeline + dai::Device device(pipeline); + device.startPipeline(); + + // Create input & output queues + auto previewQueue = device.getOutputQueue("preview", 8, false); + auto manipQueue = device.getOutputQueue("manip", 8, false); + auto manipInQueue = device.getInputQueue("manipCfg"); + + std::vector frameQueues {previewQueue, manipQueue}; + + // keep processing data + int key = -1; + float angleDeg = 0; + float rotateRate = 1.0; + int resizeFactor = 0, resizeX, resizeY; + bool testFourPt = false; + int warpIdx = -1; + + printControls(); + + while (key != 'q') { + if (key >= 0) { + printf("Pressed: %c | ", key); + if (key == KEY_ROTATE_DECR || key == KEY_ROTATE_INCR) { + if (key == KEY_ROTATE_DECR) { + if (rotateRate > -ROTATE_RATE_MAX) + rotateRate -= ROTATE_RATE_INC; + } else if (key == KEY_ROTATE_INCR) { + if (rotateRate < ROTATE_RATE_MAX) + rotateRate += ROTATE_RATE_INC; + } + testFourPt = false; + printf("Crop rotated rectangle, rate: %g degrees", rotateRate); + } else if (key == KEY_RESIZE_INC) { + resizeFactor++; + if (resizeFactor > RESIZE_FACTOR_MAX) { + resizeFactor = 0; + printf("Crop region not resized"); + } else { + resizeX = RESIZE_MAX_W / resizeFactor; + resizeY = RESIZE_MAX_H / resizeFactor; + printf("Crop region resized to: %d x %d", resizeX, resizeY); + } + } else if (key == KEY_WARP_TEST_CYCLE) { + resizeFactor = 0; // Disable resizing initially + warpIdx = (warpIdx + 1) % warpList.size(); + printf("Warp 4-point transform, %s", warpList[warpIdx].description); + testFourPt = true; + } else if (key == 'h') { + printControls(); + } + printf("\n"); + } + + // Send an updated config with continuous rotate, or after a key press + if (key >= 0 || (!testFourPt && std::abs(rotateRate) > 0.0001)) { + dai::ImageManipConfig cfg; + if (testFourPt) { + cfg.setWarpTransformFourPoints(warpList[warpIdx].points, + warpList[warpIdx].normalizedCoords); + } else { + angleDeg += rotateRate; + dai::RotatedRect rr = { + {320, 240}, // center + {640, 480}, //{400, 400}, // size + angleDeg + }; + bool normalized = false; + cfg.setCropRotatedRect(rr, normalized); + } + if (resizeFactor > 0) { + cfg.setResize(resizeX, resizeY); + } + //cfg.setWarpBorderFillColor(255, 0, 0); + //cfg.setWarpBorderReplicatePixels(); + manipInQueue->send(cfg); + } + + for (const auto& q : frameQueues) { + auto img = q->get(); + auto mat = toMat(img->getData(), img->getWidth(), img->getHeight(), 3, 1); + cv::imshow(q->getName(), mat); + } + key = cv::waitKey(1); + } +} diff --git a/include/depthai/pipeline/datatype/CameraControl.hpp b/include/depthai/pipeline/datatype/CameraControl.hpp index b01b7e869..73d0b1e49 100644 --- a/include/depthai/pipeline/datatype/CameraControl.hpp +++ b/include/depthai/pipeline/datatype/CameraControl.hpp @@ -14,6 +14,12 @@ class CameraControl : public Buffer { RawCameraControl& cfg; public: + using AutoFocusMode = RawCameraControl::AutoFocusMode; + using AntiBandingMode = RawCameraControl::AntiBandingMode; + using AutoWhiteBalanceMode = RawCameraControl::AutoWhiteBalanceMode; + using SceneMode = RawCameraControl::SceneMode; + using EffectMode = RawCameraControl::EffectMode; + CameraControl(); explicit CameraControl(std::shared_ptr ptr); virtual ~CameraControl() = default; @@ -21,6 +27,38 @@ class CameraControl : public Buffer { // Functions to set properties void setCaptureStill(bool capture); + void setStartStreaming(); + void setStopStreaming(); + + // Focus + void setAutoFocusMode(AutoFocusMode mode); + void setAutoFocusTrigger(); + void setAutoFocusRegion(uint16_t startX, uint16_t startY, uint16_t width, uint16_t height); + void setManualFocus(uint8_t lensPosition); + + // Exposure + void setAutoExposureEnable(); + void setAutoExposureLock(bool lock); + void setAutoExposureRegion(uint16_t startX, uint16_t startY, uint16_t width, uint16_t height); + void setAutoExposureCompensation(int8_t compensation); + void setAntiBandingMode(AntiBandingMode mode); + void setManualExposure(uint32_t exposureTimeUs, uint32_t sensitivityIso); + + // White Balance + void setAutoWhiteBalanceMode(AutoWhiteBalanceMode mode); + void setAutoWhiteBalanceLock(bool lock); + + // Other image controls + void setBrightness(uint16_t value); // TODO move to AE? + void setContrast(uint16_t value); + void setSaturation(uint16_t value); + void setSharpness(uint16_t value); + void setNoiseReductionStrength(uint16_t value); + void setLumaDenoise(uint16_t value); + void setChromaDenoise(uint16_t value); + void setSceneMode(SceneMode mode); + void setEffectMode(EffectMode mode); + // Functions to retrieve properties bool getCaptureStill() const; }; diff --git a/include/depthai/pipeline/datatype/ImageManipConfig.hpp b/include/depthai/pipeline/datatype/ImageManipConfig.hpp index 022e213cc..e81ce3ea5 100644 --- a/include/depthai/pipeline/datatype/ImageManipConfig.hpp +++ b/include/depthai/pipeline/datatype/ImageManipConfig.hpp @@ -20,11 +20,20 @@ class ImageManipConfig : public Buffer { // Functions to set properties void setCropRect(float xmin, float ymin, float xmax, float ymax); + void setCropRotatedRect(RotatedRect rr, bool normalizedCoords = true); void setCenterCrop(float ratio, float whRatio = 1.0f); + void setWarpTransformFourPoints(std::vector pt, bool normalizedCoords); + void setWarpTransformMatrix3x3(std::vector mat); + void setWarpBorderReplicatePixels(); + void setWarpBorderFillColor(int red, int green, int blue); + void setRotationDegrees(float deg); + void setRotationRadians(float rad); void setResize(int w, int h); void setResizeThumbnail(int w, int h, int bgRed = 0, int bgGreen = 0, int bgBlue = 0); void setFrameType(dai::RawImgFrame::Type name); void setHorizontalFlip(bool flip); + void setReusePreviousImage(bool reuse); + void setSkipCurrentImage(bool skip); // Functions to retrieve properties float getCropXMin() const; diff --git a/include/depthai/pipeline/node/ColorCamera.hpp b/include/depthai/pipeline/node/ColorCamera.hpp index 73f1e30f4..29ff93e04 100644 --- a/include/depthai/pipeline/node/ColorCamera.hpp +++ b/include/depthai/pipeline/node/ColorCamera.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "depthai/pipeline/Node.hpp" // shared @@ -16,9 +18,13 @@ class ColorCamera : public Node { nlohmann::json getProperties() override; std::shared_ptr clone() override; + std::shared_ptr rawControl; + public: ColorCamera(const std::shared_ptr& par, int64_t nodeId); + CameraControl initialControl; + Input inputConfig{*this, "inputConfig", Input::Type::SReceiver, {{DatatypeEnum::ImageManipConfig, false}}}; Input inputControl{*this, "inputControl", Input::Type::SReceiver, {{DatatypeEnum::CameraControl, false}}}; diff --git a/include/depthai/pipeline/node/ImageManip.hpp b/include/depthai/pipeline/node/ImageManip.hpp index 8c0bf3f12..23ed9df59 100644 --- a/include/depthai/pipeline/node/ImageManip.hpp +++ b/include/depthai/pipeline/node/ImageManip.hpp @@ -19,23 +19,24 @@ class ImageManip : public Node { std::shared_ptr clone() override; std::shared_ptr rawConfig; - ImageManipConfig config; public: ImageManip(const std::shared_ptr& par, int64_t nodeId); + ImageManipConfig initialConfig; + Input inputConfig{*this, "inputConfig", Input::Type::SReceiver, {{DatatypeEnum::ImageManipConfig, true}}}; Input inputImage{*this, "inputImage", Input::Type::SReceiver, {{DatatypeEnum::ImgFrame, true}}}; Output out{*this, "out", Output::Type::MSender, {{DatatypeEnum::ImgFrame, true}}}; - // Functions to set ImageManipConfig - void setCropRect(float xmin, float ymin, float xmax, float ymax); - void setCenterCrop(float ratio, float whRatio = 1.0f); - void setResize(int w, int h); - void setResizeThumbnail(int w, int h, int bgRed = 0, int bgGreen = 0, int bgBlue = 0); - void setFrameType(dai::RawImgFrame::Type name); - void setHorizontalFlip(bool flip); + // Functions to set ImageManipConfig - deprecated + [[deprecated("Use 'initialConfig.setCropRect()' instead")]] void setCropRect(float xmin, float ymin, float xmax, float ymax); + [[deprecated("Use 'initialConfig.setCenterCrop()' instead")]] void setCenterCrop(float ratio, float whRatio = 1.0f); + [[deprecated("Use 'initialConfig.setResize()' instead")]] void setResize(int w, int h); + [[deprecated("Use 'initialConfig.setResizeThumbnail()' instead")]] void setResizeThumbnail(int w, int h, int bgRed = 0, int bgGreen = 0, int bgBlue = 0); + [[deprecated("Use 'initialConfig.setFrameType()' instead")]] void setFrameType(dai::RawImgFrame::Type name); + [[deprecated("Use 'initialConfig.setHorizontalFlip()' instead")]] void setHorizontalFlip(bool flip); // Functions to set properties void setWaitForConfigInput(bool wait); diff --git a/include/depthai/pipeline/node/MonoCamera.hpp b/include/depthai/pipeline/node/MonoCamera.hpp index 45559d345..385e6cfba 100644 --- a/include/depthai/pipeline/node/MonoCamera.hpp +++ b/include/depthai/pipeline/node/MonoCamera.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "depthai/pipeline/Node.hpp" // shared @@ -17,9 +19,15 @@ class MonoCamera : public Node { nlohmann::json getProperties() override; std::shared_ptr clone() override; + std::shared_ptr rawControl; + public: MonoCamera(const std::shared_ptr& par, int64_t nodeId); + CameraControl initialControl; + + Input inputControl{*this, "inputControl", Input::Type::SReceiver, {{DatatypeEnum::CameraControl, false}}}; + Output out{*this, "out", Output::Type::MSender, {{DatatypeEnum::ImgFrame, false}}}; // Set which board socket to use diff --git a/include/depthai/pipeline/node/NeuralNetwork.hpp b/include/depthai/pipeline/node/NeuralNetwork.hpp index 45d35c066..654957206 100644 --- a/include/depthai/pipeline/node/NeuralNetwork.hpp +++ b/include/depthai/pipeline/node/NeuralNetwork.hpp @@ -42,6 +42,10 @@ class NeuralNetwork : public Node { // Specify local filesystem path to load the blob (which gets loaded at loadAssets) void setBlobPath(const std::string& path); void setNumPoolFrames(int numFrames); + void setNumInferenceThreads(int numThreads); + // Zero means AUTO. TODO add AUTO in NeuralNetworkProperties + int getNumInferenceThreads(); + // TODO add getters for other API }; } // namespace node diff --git a/shared/depthai-shared b/shared/depthai-shared index 175cd09e3..47246f471 160000 --- a/shared/depthai-shared +++ b/shared/depthai-shared @@ -1 +1 @@ -Subproject commit 175cd09e3a114b63bc972f78287662e3334507ce +Subproject commit 47246f471a06608c0837aa1644ddc77df89c1eff diff --git a/src/pipeline/datatype/CameraControl.cpp b/src/pipeline/datatype/CameraControl.cpp index be8d19c8b..d58c52ba5 100644 --- a/src/pipeline/datatype/CameraControl.cpp +++ b/src/pipeline/datatype/CameraControl.cpp @@ -13,11 +13,119 @@ CameraControl::CameraControl(std::shared_ptr ptr) : Buffer(std // Functions to set properties void CameraControl::setCaptureStill(bool capture) { // Enable capture - cfg.captureStill = capture; + cfg.setCommand(RawCameraControl::Command::STILL_CAPTURE, capture); +} + +void CameraControl::setStartStreaming() { + cfg.setCommand(RawCameraControl::Command::START_STREAM); +} +void CameraControl::setStopStreaming() { + cfg.setCommand(RawCameraControl::Command::STOP_STREAM); +} + +// Focus +void CameraControl::setAutoFocusMode(AutoFocusMode mode) { + cfg.setCommand(RawCameraControl::Command::AF_MODE); + cfg.autoFocusMode = mode; +} +void CameraControl::setAutoFocusTrigger() { + cfg.setCommand(RawCameraControl::Command::AF_TRIGGER); +} +void CameraControl::setAutoFocusRegion(uint16_t startX, uint16_t startY, uint16_t width, uint16_t height) { + cfg.setCommand(RawCameraControl::Command::AF_REGION); + cfg.afRegion.x = startX; + cfg.afRegion.y = startY; + cfg.afRegion.width = width; + cfg.afRegion.height = height; + cfg.afRegion.priority = 1; // TODO +} +void CameraControl::setManualFocus(uint8_t lensPosition) { + cfg.setCommand(RawCameraControl::Command::MOVE_LENS); + cfg.lensPosition = lensPosition; + setAutoFocusMode(AutoFocusMode::OFF); // TODO added for initialConfig case +} + +// Exposure +void CameraControl::setAutoExposureEnable() { + cfg.setCommand(RawCameraControl::Command::AE_AUTO); +} +void CameraControl::setAutoExposureLock(bool lock) { + cfg.setCommand(RawCameraControl::Command::AE_LOCK); + cfg.aeLockMode = lock; +} +void CameraControl::setAutoExposureRegion(uint16_t startX, uint16_t startY, uint16_t width, uint16_t height) { + cfg.setCommand(RawCameraControl::Command::AE_REGION); + cfg.aeRegion.x = startX; + cfg.aeRegion.y = startY; + cfg.aeRegion.width = width; + cfg.aeRegion.height = height; + cfg.aeRegion.priority = 1; // TODO +} +void CameraControl::setAutoExposureCompensation(int8_t compensation) { + cfg.setCommand(RawCameraControl::Command::EXPOSURE_COMPENSATION); + cfg.expCompensation = compensation; +} +void CameraControl::setAntiBandingMode(AntiBandingMode mode) { + cfg.setCommand(RawCameraControl::Command::ANTIBANDING_MODE); + cfg.antiBandingMode = mode; +} +void CameraControl::setManualExposure(uint32_t exposureTimeUs, uint32_t sensitivityIso) { + cfg.setCommand(RawCameraControl::Command::AE_MANUAL); + cfg.expManual.exposureTimeUs = exposureTimeUs; + cfg.expManual.sensitivityIso = sensitivityIso; + cfg.expManual.frameDurationUs = 0; // TODO +} + +// White Balance +void CameraControl::setAutoWhiteBalanceMode(AutoWhiteBalanceMode mode) { + cfg.setCommand(RawCameraControl::Command::AWB_MODE); + cfg.awbMode = mode; +} +void CameraControl::setAutoWhiteBalanceLock(bool lock) { + cfg.setCommand(RawCameraControl::Command::AWB_LOCK); + cfg.awbLockMode = lock; +} + +// Other image controls +void CameraControl::setBrightness(uint16_t value) { + cfg.setCommand(RawCameraControl::Command::BRIGHTNESS); + cfg.brightness = value; +} +void CameraControl::setContrast(uint16_t value) { + cfg.setCommand(RawCameraControl::Command::CONTRAST); + cfg.contrast = value; +} +void CameraControl::setSaturation(uint16_t value) { + cfg.setCommand(RawCameraControl::Command::SATURATION); + cfg.saturation = value; +} +void CameraControl::setSharpness(uint16_t value) { + cfg.setCommand(RawCameraControl::Command::SHARPNESS); + cfg.sharpness = value; +} +void CameraControl::setNoiseReductionStrength(uint16_t value) { + cfg.setCommand(RawCameraControl::Command::NOISE_REDUCTION_STRENGTH); + cfg.noiseReductionStrength = value; +} +void CameraControl::setLumaDenoise(uint16_t value) { + cfg.setCommand(RawCameraControl::Command::LUMA_DENOISE); + cfg.lumaDenoise = value; +} +void CameraControl::setChromaDenoise(uint16_t value) { + cfg.setCommand(RawCameraControl::Command::CHROMA_DENOISE); + cfg.chromaDenoise = value; +} +void CameraControl::setSceneMode(SceneMode mode) { + cfg.setCommand(RawCameraControl::Command::SCENE_MODE); + cfg.sceneMode = mode; +} +void CameraControl::setEffectMode(EffectMode mode) { + cfg.setCommand(RawCameraControl::Command::EFFECT_MODE); + cfg.effectMode = mode; } bool CameraControl::getCaptureStill() const { - return cfg.captureStill; + return cfg.getCommand(RawCameraControl::Command::STILL_CAPTURE); } } // namespace dai diff --git a/src/pipeline/datatype/ImageManipConfig.cpp b/src/pipeline/datatype/ImageManipConfig.cpp index 6953436ab..7537feab2 100644 --- a/src/pipeline/datatype/ImageManipConfig.cpp +++ b/src/pipeline/datatype/ImageManipConfig.cpp @@ -1,5 +1,9 @@ +// First, as other headers may include +#define _USE_MATH_DEFINES #include "depthai/pipeline/datatype/ImageManipConfig.hpp" +#include + namespace dai { std::shared_ptr ImageManipConfig::serialize() const { @@ -25,6 +29,45 @@ void ImageManipConfig::setCropRect(float xmin, float ymin, float xmax, float yma cfg.cropConfig.cropRect.ymax = ymax; } +void ImageManipConfig::setCropRotatedRect(RotatedRect rr, bool normalizedCoords) { + // Enable crop stage and extended flags + cfg.enableCrop = true; + cfg.cropConfig.enableRotatedRect = true; + + cfg.cropConfig.cropRotatedRect = rr; + cfg.cropConfig.normalizedCoords = normalizedCoords; +} + +void ImageManipConfig::setWarpTransformFourPoints(std::vector pt, bool normalizedCoords) { + // Enable resize stage and extended flags + cfg.enableResize = true; + cfg.resizeConfig.enableWarp4pt = true; + cfg.resizeConfig.warpFourPoints = pt; + cfg.resizeConfig.normalizedCoords = normalizedCoords; +} + +void ImageManipConfig::setWarpTransformMatrix3x3(std::vector mat) { + // Enable resize stage and extended flags + cfg.enableResize = true; + cfg.resizeConfig.enableWarpMatrix = true; + cfg.resizeConfig.warpMatrix3x3 = mat; +} + +void ImageManipConfig::setWarpBorderReplicatePixels() { + // Enable resize stage and extended flags + cfg.enableResize = true; + cfg.resizeConfig.warpBorderReplicate = true; +} + +void ImageManipConfig::setWarpBorderFillColor(int red, int green, int blue) { + // Enable resize stage and extended flags + cfg.enableResize = true; + cfg.resizeConfig.warpBorderReplicate = false; + cfg.resizeConfig.bgRed = red; + cfg.resizeConfig.bgGreen = green; + cfg.resizeConfig.bgBlue = blue; +} + void ImageManipConfig::setCenterCrop(float ratio, float whRatio) { // Enable crop stage cfg.enableCrop = true; @@ -37,6 +80,17 @@ void ImageManipConfig::setCenterCrop(float ratio, float whRatio) { cfg.cropConfig.widthHeightAspectRatio = whRatio; } +void ImageManipConfig::setRotationDegrees(float deg) { + cfg.enableResize = true; + cfg.resizeConfig.rotationAngleDeg = deg; + cfg.resizeConfig.enableRotation = true; +} + +void ImageManipConfig::setRotationRadians(float rad) { + static constexpr float rad2degFactor = 180 / M_PI; + setRotationDegrees(rad * rad2degFactor); +} + void ImageManipConfig::setResize(int w, int h) { // Enable resize stage cfg.enableResize = true; @@ -82,6 +136,14 @@ void ImageManipConfig::setHorizontalFlip(bool flip) { cfg.formatConfig.flipHorizontal = flip; } +void ImageManipConfig::setReusePreviousImage(bool reuse) { + cfg.reusePreviousImage = reuse; +} + +void ImageManipConfig::setSkipCurrentImage(bool skip) { + cfg.skipCurrentImage = skip; +} + // Functions to retrieve properties float ImageManipConfig::getCropXMin() const { return cfg.cropConfig.cropRect.xmin; diff --git a/src/pipeline/node/ColorCamera.cpp b/src/pipeline/node/ColorCamera.cpp index edad50734..2bc2ad433 100644 --- a/src/pipeline/node/ColorCamera.cpp +++ b/src/pipeline/node/ColorCamera.cpp @@ -5,7 +5,8 @@ namespace dai { namespace node { -ColorCamera::ColorCamera(const std::shared_ptr& par, int64_t nodeId) : Node(par, nodeId) { +ColorCamera::ColorCamera(const std::shared_ptr& par, int64_t nodeId) + : Node(par, nodeId), rawControl(std::make_shared()), initialControl(rawControl) { properties.boardSocket = CameraBoardSocket::AUTO; properties.imageOrientation = CameraImageOrientation::AUTO; properties.colorOrder = ColorCameraProperties::ColorOrder::BGR; @@ -31,6 +32,7 @@ std::vector ColorCamera::getInputs() { nlohmann::json ColorCamera::getProperties() { nlohmann::json j; + properties.initialControl = *rawControl; nlohmann::to_json(j, properties); return j; } diff --git a/src/pipeline/node/ImageManip.cpp b/src/pipeline/node/ImageManip.cpp index 17a940c3d..91cfd7e29 100644 --- a/src/pipeline/node/ImageManip.cpp +++ b/src/pipeline/node/ImageManip.cpp @@ -3,7 +3,7 @@ namespace dai { namespace node { ImageManip::ImageManip(const std::shared_ptr& par, int64_t nodeId) - : Node(par, nodeId), rawConfig(std::make_shared()), config(rawConfig) {} + : Node(par, nodeId), rawConfig(std::make_shared()), initialConfig(rawConfig) {} std::string ImageManip::getName() const { return "ImageManip"; @@ -19,6 +19,7 @@ std::vector ImageManip::getOutputs() { nlohmann::json ImageManip::getProperties() { nlohmann::json j; + properties.initialConfig = *rawConfig; nlohmann::to_json(j, properties); return j; } @@ -29,32 +30,32 @@ std::shared_ptr ImageManip::clone() { // Initial ImageManipConfig void ImageManip::setCropRect(float xmin, float ymin, float xmax, float ymax) { - config.setCropRect(xmin, ymin, xmax, ymax); + initialConfig.setCropRect(xmin, ymin, xmax, ymax); properties.initialConfig = *rawConfig; } void ImageManip::setCenterCrop(float ratio, float whRatio) { - config.setCenterCrop(ratio, whRatio); + initialConfig.setCenterCrop(ratio, whRatio); properties.initialConfig = *rawConfig; } void ImageManip::setResize(int w, int h) { - config.setResize(w, h); + initialConfig.setResize(w, h); properties.initialConfig = *rawConfig; } void ImageManip::setResizeThumbnail(int w, int h, int bgRed, int bgGreen, int bgBlue) { - config.setResizeThumbnail(w, h, bgRed, bgGreen, bgBlue); + initialConfig.setResizeThumbnail(w, h, bgRed, bgGreen, bgBlue); properties.initialConfig = *rawConfig; } void ImageManip::setFrameType(dai::RawImgFrame::Type type) { - config.setFrameType(type); + initialConfig.setFrameType(type); properties.initialConfig = *rawConfig; } void ImageManip::setHorizontalFlip(bool flip) { - config.setHorizontalFlip(flip); + initialConfig.setHorizontalFlip(flip); properties.initialConfig = *rawConfig; } diff --git a/src/pipeline/node/MonoCamera.cpp b/src/pipeline/node/MonoCamera.cpp index 9bfc8ff0d..9191e117c 100644 --- a/src/pipeline/node/MonoCamera.cpp +++ b/src/pipeline/node/MonoCamera.cpp @@ -5,7 +5,8 @@ namespace dai { namespace node { -MonoCamera::MonoCamera(const std::shared_ptr& par, int64_t nodeId) : Node(par, nodeId) { +MonoCamera::MonoCamera(const std::shared_ptr& par, int64_t nodeId) + : Node(par, nodeId), rawControl(std::make_shared()), initialControl(rawControl) { properties.boardSocket = CameraBoardSocket::AUTO; properties.resolution = MonoCameraProperties::SensorResolution::THE_720_P; properties.fps = 30.0; @@ -20,11 +21,12 @@ std::vector MonoCamera::getOutputs() { } std::vector MonoCamera::getInputs() { - return {}; + return {inputControl}; } nlohmann::json MonoCamera::getProperties() { nlohmann::json j; + properties.initialControl = *rawControl; nlohmann::to_json(j, properties); return j; } diff --git a/src/pipeline/node/NeuralNetwork.cpp b/src/pipeline/node/NeuralNetwork.cpp index e5a01d0ff..b0f6b6246 100644 --- a/src/pipeline/node/NeuralNetwork.cpp +++ b/src/pipeline/node/NeuralNetwork.cpp @@ -78,5 +78,13 @@ void NeuralNetwork::setNumPoolFrames(int numFrames) { properties.numFrames = numFrames; } +void NeuralNetwork::setNumInferenceThreads(int numThreads) { + properties.numThreads = numThreads; +} + +int NeuralNetwork::getNumInferenceThreads() { + return properties.numThreads; +} + } // namespace node } // namespace dai