Simple OpenCV example

  • Hello, the example routines we provide use opencv-mobile instead of opencv. For a simple example of capturing images, you can refer to https://wiki.luckfox.com/zh/Luckfox-Pic ... ncv-mobile
  • Thank you for the reply.
    I tried that example and it does not work on the Pico Ultra.

    Code: Select all

    ./opencv-mobile-test
    opencv-mobile MIPI CSI camera with v4l2 rkaiq
    opencv-mobile HW JPG encoder with rk mpp
    Still Image Capture Example..
       devpath = /dev/video11
       driver = rkisp_v7
       card = rkisp_mainpath
       bus_info = platform:rkisp-vir0
       version = 20500
       capabilities = 84201000
       device_caps = 4201000
       fmt = UYVY 4:2:2  59565955
       fmt = Y/CbCr 4:2:2  3631564e
       fmt = Y/CrCb 4:2:2  3136564e
       fmt = Y/CrCb 4:2:0  3132564e
           size = 32 x 32  ~  2304 x 1296  (+8 +8)
       fmt = Y/CbCr 4:2:0  3231564e
       fmt = Y/CrCb 4:2:0 (N-C)  31324d4e
       fmt = Y/CbCr 4:2:0 (N-C)  32314d4e
    rkaiq log level ff1
    XCORE:K:rk_aiq_init_lib, ISP HW ver: 32
    XCORE:K:
    ************************** VERSION INFOS **************************
    version release date: 2024-2-18
             AIQ:       AIQ v5.0x5.0
    
    git logs:
    25bd14e RV1106: smart_door: release rga/isp/mpp for V1.3.0
    99d080a RV1106/RV1103: Battery/Doorbell: release kmpp/rockit-ko for V1.3.2
    6458e2a RV1106/RV1103: Battery/Doorbell: release kmpp/rockit-ko for V1.3.1
    e8dab39 RV1106: CVR: release rga/isp/mpp for V1.1.0
    a021b32 RV1106/RV1103: Battery/Doorbell: release kmpp/rockit-ko for V1.3.0
    
    ************************ VERSION INFOS END ************************
    
    XCORE:K:rk_aiq_uapi_sysctl_preInit_scene: main_scene: normal, sub_scene: day
    XCORE:E:invalid main scene len!
    
    Looking at the code, I am unsure how this could work. OpenCV assumes camera output is BGR (or RGB) by default, but the Luckfox MIPI CSI camera outputs raw YUV formats (e.g. UYVY, NV12, NV21, etc.), which OpenCV does not automatically convert.

    Code: Select all

    # v4l2-ctl -d /dev/video11 --list-formats-ext
    ioctl: VIDIOC_ENUM_FMT
            Type: Video Capture Multiplanar
    
            [0]: 'UYVY' (UYVY 4:2:2)
                    Size: Stepwise 32x32 - 2304x1296 with step 8/8
            [1]: 'NV16' (Y/CbCr 4:2:2)
                    Size: Stepwise 32x32 - 2304x1296 with step 8/8
            [2]: 'NV61' (Y/CrCb 4:2:2)
                    Size: Stepwise 32x32 - 2304x1296 with step 8/8
            [3]: 'NV21' (Y/CrCb 4:2:0)
                    Size: Stepwise 32x32 - 2304x1296 with step 8/8
            [4]: 'NV12' (Y/CbCr 4:2:0)
                    Size: Stepwise 32x32 - 2304x1296 with step 8/8
            [5]: 'NM21' (Y/CrCb 4:2:0 (N-C))
                    Size: Stepwise 32x32 - 2304x1296 with step 8/8
            [6]: 'NM12' (Y/CbCr 4:2:0 (N-C))
                    Size: Stepwise 32x32 - 2304x1296 with step 8/8
    

    I slight modified the code in the sample for debugging:

    Code: Select all

    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    
    #include <unistd.h> // sleep()
    
    int main()
    {
        fprintf(stderr, "Still Image Capture Example..\n");
        cv::VideoCapture cap;
        cap.set(cv::CAP_PROP_FRAME_WIDTH, 320);
        cap.set(cv::CAP_PROP_FRAME_HEIGHT, 240);
        cap.open(0);
        if (!cap.isOpened())
        {
            fprintf(stderr, "ERROR: Cannot open camera.\n");
            return -1;
        }
        else
            fprintf(stderr, "Opened camera..\n");
    
        const int w = cap.get(cv::CAP_PROP_FRAME_WIDTH);
        const int h = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
        fprintf(stderr, "Image Dimensions: %d x %d\n", w, h);
    
        cv::Mat bgr[9];
        for (int i = 0; i < 9; i++)
        {
            cap >> bgr[i];
            if (bgr[i].empty())
            {
                fprintf(stderr, "ERROR: Frame %d is empty\n", i);
                return -1;
            }
            fprintf(stderr, "Captured frame %d: type = %d, channels = %d\n",
                    i, bgr[i].type(), bgr[i].channels());
    
            // Save intermediate frames for debugging
            std::string filename = "frame_" + std::to_string(i) + ".jpg";
            cv::imwrite(filename, bgr[i]);
            sleep(1);
        }
    
        cap.release();
    
        // combine into big image
        {
            cv::Mat out(h * 3, w * 3, CV_8UC3);
            bgr[0].copyTo(out(cv::Rect(0, 0, w, h)));
            bgr[1].copyTo(out(cv::Rect(w, 0, w, h)));
            bgr[2].copyTo(out(cv::Rect(w * 2, 0, w, h)));
            bgr[3].copyTo(out(cv::Rect(0, h, w, h)));
            bgr[4].copyTo(out(cv::Rect(w, h, w, h)));
            bgr[5].copyTo(out(cv::Rect(w * 2, h, w, h)));
            bgr[6].copyTo(out(cv::Rect(0, h * 2, w, h)));
            bgr[7].copyTo(out(cv::Rect(w, h * 2, w, h)));
            bgr[8].copyTo(out(cv::Rect(w * 2, h * 2, w, h)));
    
            if (!cv::imwrite("out.jpg", out))
            {
                fprintf(stderr, "ERROR: Failed to write out.jpg\n");
                return -1;
            }
        }
    
        return 0;
    }
    
    
    Any help would be appreciated.
  • Please check if the rkipc program is closed. If it is using the camera device, the routine will not be able to run.
  • I ran RKlunch-stop.sh before running the code

    lsmod
    Module Size Used by Tainted: G
    aic8800_btlpm 1719 0
    aic8800_fdrv 285463 0
    aic8800_bsp 53767 2 aic8800_btlpm,aic8800_fdrv
    aes_generic 24532 0
    ccm 6847 0
    ctr 2606 0
    libarc4 799 0
    pwm_bl 4629 0
    cfg80211 168973 1 aic8800_fdrv
    rve 23436 0
    rockit 225880 0
    rknpu 27019 0
    mpp_vcodec 414257 1 rockit
    rga3 90762 1 rockit
    phy_rockchip_csi2_dphy 9338 0
    phy_rockchip_csi2_dphy_hw 10066 0
    video_rkisp 171838 1 rockit
    video_rkcif 162117 1 rockit
    sc3336 9940 1
    rk_dvbm 5941 2 mpp_vcodec,video_rkisp
    Last edited by RogerTheFox on 2025-07-18 14:48, edited 1 time in total.
  • I compiled again, made sure I ran RkLunch-stop.sh and can confirm the example worked. Thank you.