oneShot Sample with opencv imshow error

the original ~/tegra_multimedia_api/argus/samples were built and run without issue. I need capture images from Leopard IMX185 camera and display it on opencv. So simply modified oneShort sample to use opencv with some suggestions on this forum. Then I ran into this error,

nvidia@tegra-ubuntu:~/tegra_multimedia_api/argus/build/samples/oneShot$ ./argus_oneshot
Executing Argus Sample: argus_oneshot
Argus Version: 0.96.2 (multi-process)

(img:13810): Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported
Trace/breakpoint trap
nvidia@tegra-ubuntu:~/tegra_multimedia_api/argus/build/samples/oneShot$

Is Argus using gtk3.0 and opencv uses gtk2.0?

Here is my oneShot/main.cc. The changes are inside “#ifdef ORIGINAL_JPEG_IMAGE”.

nvidia@tegra-ubuntu:~/tegra_multimedia_api/argus/samples/oneShot$ cat main.cpp 
/*
 * Copyright (c) 2016-2017, 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 "../../../include/nvbuf_utils.h"
#include "Options.h"
#include <Argus/Argus.h>
#include <Argus/Types.h>
#include <EGLStream/Frame.h>

#include <EGLStream/EGLStream.h>
#include <EGLStream/NV/ImageNativeBuffer.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

using namespace EGLStream;

#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;                                                     \
    }                                                                          \
  }

static const uint32_t DEFAULT_CAMERA_INDEX = 0;

/*
 * Program: oneShot
 * Function: Capture a single image from a camera device and write to a JPG file
 * Purpose: To demonstrate the most simplistic approach to getting the Argus
 * Framework
 *          running, submitting a capture request, retrieving the resulting
 * image and
 *          then writing the image as a JPEG formatted file.
 */

int main(int argc, char **argv) {
  printf("Executing Argus Sample: %s\n", basename(argv[0]));

  ArgusSamples::Value<uint32_t> cameraIndex(DEFAULT_CAMERA_INDEX);
  ArgusSamples::Options options(basename(argv[0]));
  options.addOption(ArgusSamples::createValueOption(
      "device", 'd', "INDEX", "Camera index.", cameraIndex));

  if (!options.parse(argc, argv))
    return EXIT_FAILURE;
  if (options.requestedExit())
    return EXIT_SUCCESS;

  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");
  printf("Argus Version: %s\n", iCameraProvider->getVersion().c_str());

  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");
  if (cameraDevices.size() <= cameraIndex.get()) {
    printf("Camera device specifed on command line is not available\n");
    return EXIT_FAILURE;
  }

  Argus::UniqueObj<Argus::CaptureSession> captureSession(
      iCameraProvider->createCaptureSession(cameraDevices[cameraIndex.get()],
                                            &status));

  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.
   */

  Argus::UniqueObj<Argus::OutputStreamSettings> streamSettings(
      iSession->createOutputStreamSettings());

  Argus::IOutputStreamSettings *iStreamSettings =
      Argus::interface_cast<Argus::IOutputStreamSettings>(streamSettings);
  EXIT_IF_NULL(iStreamSettings, "Cannot get OutputStreamSettings Interface");
  iStreamSettings->setPixelFormat(Argus::PIXEL_FMT_YCbCr_420_888);
  iStreamSettings->setResolution(Argus::Size2D<uint32_t>(640, 480));
  iStreamSettings->setMetadataEnable(true);

  Argus::UniqueObj<Argus::OutputStream> stream(
      iSession->createOutputStream(streamSettings.get()));

  Argus::IStream *iStream = Argus::interface_cast<Argus::IStream>(stream);
  EXIT_IF_NULL(iStream, "Cannot get OutputStream Interface");

  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");

  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");

#ifdef ORIGINAL_JPEG_IMAGE
  /*
   * 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("oneShot.jpg");
  EXIT_IF_NOT_OK(status, "Failed to write JPEG");
#else
  CvSize m_framesize(640, 480);
  // Acquire a Frame.
  Argus::UniqueObj<EGLStream::Frame> frame(iFrameConsumer->acquireFrame());
  EGLStream::IFrame *iFrame = Argus::interface_cast<IFrame>(frame);
  EXIT_IF_NULL(iFrame, "Failed to get IFrame interface");

  // Get the Frame's Image.
  EGLStream::Image *image = iFrame->getImage();
  EGLStream::NV::IImageNativeBuffer *iImageNativeBuffer =
      Argus::interface_cast<EGLStream::NV::IImageNativeBuffer>(image);
  EXIT_IF_NULL(iImageNativeBuffer, "Failed to create an IImageNativeBuffer");

  int fd = iImageNativeBuffer->createNvBuffer(
      Argus::Size2D<uint32_t>{m_framesize.width, m_framesize.height},
      NvBufferColorFormat_YUV420, NvBufferLayout_Pitch, &status);
  EXIT_IF_NOT_OK(status, "Failed to create a native buffer");

  NvBufferParams params;
  NvBufferGetParams(fd, &params);

  int fsize = params.pitch[0] * m_framesize.height;
  char *data_mem = (char *)mmap(NULL, fsize, PROT_READ | PROT_WRITE, MAP_SHARED,
                                fd, params.offset[0]);
  if (data_mem == MAP_FAILED)
    printf("mmap failed : %s\n", strerror(errno));

  cv::Mat imgbuf = cv::Mat(m_framesize.height, m_framesize.width, CV_8UC1,
                           data_mem, params.pitch[0]);
  cv::imshow("img", imgbuf);
  cv::waitKey(1);
  NvBufferDestroy(fd);
#endif
  return EXIT_SUCCESS;
}

thanks!

Steve

Hi,

Yes, you are correct, Argus is using gtk3. Since we cannot modify imshow, would you mind using EGLrender?

Thanks, Wayne. I’m making progress with another sample program tegra_multimedia_api/samples/11_camera_object_identification. I removed CAFFE related stuff which I don’t need.

So the flow is MPX185 → ISP → Argus-> EGLstream → V4L2 buffer → opencv. Not sure whether there is a better way, but this one works.