Here’s example cropped without scaling.
/*
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of NVIDIA CORPORATION nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <Argus/Argus.h>
#include <EGLStream/EGLStream.h>
#define EXIT_IF_NULL(val,msg) \
{if (!val) {printf("%s\n",msg); return EXIT_FAILURE;}}
#define EXIT_IF_NOT_OK(val,msg) \
{if (val!=Argus::STATUS_OK) {printf("%s\n",msg); return EXIT_FAILURE;}}
/*
* Program: oneShotCropped
* Function: Capture a single cropped image from a camera device and write to a JPG file
* Purpose: To demonstrate the use of the setSourceClipRect and the configuration of the
* stream parameters to get an unscaled image as a result.
*/
int main(int argc, char** argv)
{
const uint64_t FIVE_SECONDS_IN_NANOSECONDS = 5000000000;
std::vector<Argus::CameraDevice*> cameraDevices;
/*
* Set up Argus API Framework, identify available camera devices, and create
* a capture session for the first available device
*/
Argus::UniqueObj<Argus::CameraProvider> cameraProvider(Argus::CameraProvider::create());
Argus::ICameraProvider *iCameraProvider =
Argus::interface_cast<Argus::ICameraProvider>(cameraProvider);
EXIT_IF_NULL(iCameraProvider, "Cannot get core camera provider interface");
Argus::Status status = iCameraProvider->getCameraDevices(&cameraDevices);
EXIT_IF_NOT_OK(status, "Failed to get camera devices");
EXIT_IF_NULL(cameraDevices.size(), "No camera devices available");
Argus::CameraDevice *cameraDevice = cameraDevices[0];
Argus::ICameraProperties *iCameraProperties = Argus::interface_cast<Argus::ICameraProperties>(cameraDevice);
EXIT_IF_NULL(iCameraProperties, "Failed to get ICameraProperties interface\n");
Argus::UniqueObj<Argus::CaptureSession> captureSession(
iCameraProvider->createCaptureSession(cameraDevice, &status));
std::vector<Argus::SensorMode*> sensorModes;
iCameraProperties->getAllSensorModes(&sensorModes);
EXIT_IF_NULL(sensorModes.size(), "Failed to get sensor modes\n");
Argus::ISensorMode *iSensorMode = Argus::interface_cast<Argus::ISensorMode>(sensorModes[0]);
EXIT_IF_NULL(iSensorMode, "Failed to get sensor mode interface\n");
Argus::ICaptureSession *iSession =
Argus::interface_cast<Argus::ICaptureSession>(captureSession);
EXIT_IF_NULL(iSession, "Cannot get Capture Session Interface");
/*
* Creates the stream between the Argus camera image capturing
* sub-system (producer) and the image acquisition code (consumer). A consumer object is
* created from the stream to be used to request the image frame. A successfully submitted
* capture request activates the stream's functionality to eventually make a frame available
* for acquisition.
*/
/*
* There is incorrect behavior in the processing of the setSourceClipRect() function
* and the sizing of the buffers. As this problem is being overcome internnaly and will be
* released at a later date, a method to allow application development to proceed with
* the desired result of a non-rescaled crop has been determined.
*
* By specifying a full sensor resolution on a seperate OutputStream, the internal
* behavior of the image processing will be modified to NOT downscale the output
* image before cropping, and then upscaling it afterwards.
*
* So all the following code segments that relate to a fullRes data object or interface
* are specifically added to insure that no scaling is applied. This elements are:
*
* fullResOutputStreamSettings
* iFullResOutputStreamSettings
* fullResStream
* fullResConsumer
* iFullResFrameConsumer
*
*/
Argus::UniqueObj<Argus::OutputStreamSettings> fullResOutputStreamSettings(
iSession->createOutputStreamSettings());
Argus::UniqueObj<Argus::OutputStreamSettings> outputStreamSettings(
iSession->createOutputStreamSettings());
Argus::IOutputStreamSettings *iFullResOutputStreamSettings =
Argus::interface_cast<Argus::IOutputStreamSettings>(fullResOutputStreamSettings);
EXIT_IF_NULL(iFullResOutputStreamSettings, "Cannot get Full Res OutputStreamSettings Interface");
iFullResOutputStreamSettings->setPixelFormat(Argus::PIXEL_FMT_YCbCr_420_888);
Argus::IOutputStreamSettings *iOutputStreamSettings =
Argus::interface_cast<Argus::IOutputStreamSettings>(outputStreamSettings);
EXIT_IF_NULL(iOutputStreamSettings, "Cannot get OutputStreamSettings Interface");
iOutputStreamSettings->setPixelFormat(Argus::PIXEL_FMT_YCbCr_420_888);
// This call sets the stream resolution to the sensor resolution
iFullResOutputStreamSettings->setResolution(Argus::Size2D<uint32_t>(
iSensorMode->getResolution().width(), iSensorMode->getResolution().height()));
// This call sets the stream resolution to the crop size
iOutputStreamSettings->setResolution(Argus::Size2D<uint32_t>(
iSensorMode->getResolution().width() / 2, iSensorMode->getResolution().height() / 2));
Argus::UniqueObj<Argus::OutputStream> fullResStream(
iSession->createOutputStream(fullResOutputStreamSettings.get()));
Argus::UniqueObj<Argus::OutputStream> stream(
iSession->createOutputStream(outputStreamSettings.get()));
Argus::IStream *iStream = Argus::interface_cast<Argus::IStream>(stream);
EXIT_IF_NULL(iStream, "Cannot get OutputStream Interface");
Argus::UniqueObj<EGLStream::FrameConsumer> fullResConsumer(
EGLStream::FrameConsumer::create(fullResStream.get()));
EGLStream::IFrameConsumer *iFullResFrameConsumer =
Argus::interface_cast<EGLStream::IFrameConsumer>(fullResConsumer);
EXIT_IF_NULL(iFullResFrameConsumer, "Failed to initialize full res Consumer");
Argus::UniqueObj<EGLStream::FrameConsumer> consumer(
EGLStream::FrameConsumer::create(stream.get()));
EGLStream::IFrameConsumer *iFrameConsumer =
Argus::interface_cast<EGLStream::IFrameConsumer>(consumer);
EXIT_IF_NULL(iFrameConsumer, "Failed to initialize Consumer");
Argus::UniqueObj<Argus::Request> request(
iSession->createRequest(Argus::CAPTURE_INTENT_STILL_CAPTURE));
Argus::IRequest *iRequest = Argus::interface_cast<Argus::IRequest>(request);
EXIT_IF_NULL(iRequest, "Failed to get capture request interface");
Argus::IStreamSettings* iStreamSettings =
Argus::interface_cast<Argus::IStreamSettings>(
iRequest->getStreamSettings(stream.get()));
EXIT_IF_NULL(iStreamSettings, "Cannot get StreamSettings Interface");
// This calls crops the image by 50% in each dimension and centers the image
status = iStreamSettings->setSourceClipRect(
Argus::Rectangle<float>(0.25f, 0.25f, 0.75f, 0.75f));
EXIT_IF_NOT_OK(status, "Failed setSourceClipRect");
status = iRequest->enableOutputStream(fullResStream.get());
EXIT_IF_NOT_OK(status, "Failed to enable Full Res stream in capture request");
status = iRequest->enableOutputStream(stream.get());
EXIT_IF_NOT_OK(status, "Failed to enable stream in capture request");
uint32_t requestId = iSession->capture(request.get());
EXIT_IF_NULL(requestId, "Failed to submit capture request");
/*
* Acquire a frame generated by the capture request, get the image from the frame
* and create a .JPG file of the captured image
*/
Argus::UniqueObj<EGLStream::Frame> frame(
iFrameConsumer->acquireFrame(FIVE_SECONDS_IN_NANOSECONDS, &status));
EGLStream::IFrame *iFrame = Argus::interface_cast<EGLStream::IFrame>(frame);
EXIT_IF_NULL(iFrame, "Failed to get IFrame interface");
EGLStream::Image *image = iFrame->getImage();
EXIT_IF_NULL(image, "Failed to get Image from iFrame->getImage()");
EGLStream::IImageJPEG *iImageJPEG = Argus::interface_cast<EGLStream::IImageJPEG>(image);
EXIT_IF_NULL(iImageJPEG, "Failed to get ImageJPEG Interface");
status = iImageJPEG->writeJPEG("oneShotCropped.jpg");
EXIT_IF_NOT_OK(status, "Failed to write JPEG");
return EXIT_SUCCESS;
}