Incorrect Colour Output on Image Frames from OV5640 sensor using MIPI CSI

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Incorrect Colour Output on Image Frames from OV5640 sensor using MIPI CSI

615 Views
JonMcLeanSMC
Contributor II

Hi,

 

We’re currently trying to get 720p colour images from an OV5640 camera however we’re running into an issue that is causing the colours to be displayed incorrect. Currently we have configured the receiver to use XRGB888 (seems to one of the few that works as discussed here) and the camera device to output u

se a 16 bit RGB565. This can be seen in the setup code below:

#define CAMERA_BUFFER_BPP 4
#define CAMERA_BUFFER_COUNT 2 /* Number of buffers used by the CSI loop */
#define CAMERA_FRAME_HEIGHT        720
#define CAMERA_FRAME_WIDTH         1280
#define CAMERA_FRAME_RATE    30
#define CAMERA_CONTROL_FLAGS (kCAMERA_HrefActiveHigh | kCAMERA_DataLatchOnRisingEdge)
#define CAMERA_BUFFER_ALIGN  64
#define CAMERA_MIPI_CSI_LANE 2
status_t CAMERA_Initialise() {

    camera_config_t config;
    memset(&config, 0, sizeof(config));

    BOARD_InitCameraResource();

    config.pixelFormat = kVIDEO_PixelFormatXRGB8888;
    config.bytesPerPixel = CAMERA_BUFFER_BPP;
    config.resolution = FSL_VIDEO_RESOLUTION(CAMERA_FRAME_WIDTH, CAMERA_FRAME_HEIGHT);
    config.frameBufferLinePitch_Bytes = CAMERA_FRAME_WIDTH * CAMERA_BUFFER_BPP;
    config.interface = kCAMERA_InterfaceGatedClock;
    config.controlFlags = CAMERA_CONTROL_FLAGS;
    config.framePerSec = CAMERA_FRAME_RATE;

    status_t receiverStatus = CAMERA_RECEIVER_Init(&cameraReceiver, &config, NULL, NULL);
    if(receiverStatus != kStatus_Success) {
        CAM_PRINTF("Failed to initialise camera receiver, received status: %i \r\n", receiverStatus);
        return receiverStatus;
    }

    BOARD_InitMipiCsi();

    config.pixelFormat = kVIDEO_PixelFormatRGB565;
    config.bytesPerPixel = 2;
    config.resolution = FSL_VIDEO_RESOLUTION(CAMERA_FRAME_WIDTH, CAMERA_FRAME_HEIGHT);
    config.interface = kCAMERA_InterfaceMIPI;
    config.controlFlags = CAMERA_CONTROL_FLAGS;
    config.framePerSec = CAMERA_FRAME_RATE;
    config.csiLanes = CAMERA_MIPI_CSI_LANE;

    status_t deviceStatus = CAMERA_DEVICE_Init(&cameraDevice, &config);
    if(deviceStatus != kStatus_Success) {
        CAM_PRINTF("Failed to initialise camera device, received status: %i \r\n", deviceStatus);
        return deviceStatus;
    }

    status_t startStatus = CAMERA_DEVICE_Start(&cameraDevice);
    if(startStatus != kStatus_Success) {
        CAM_PRINTF("Failed to start camera device, received status: %i \r\n", startStatus);
        return startStatus;
    }

    for(int i = 0; i < CAMERA_BUFFER_COUNT; i++) {
        CAM_PRINTF("Submitting Empty Buffer #%i \r\n", i);
        status_t bufferStatus = CAMERA_RECEIVER_SubmitEmptyBuffer(&cameraReceiver, (uint32_t)(camBuffer[i]));
        if(bufferStatus != kStatus_Success) {
            CAM_PRINTF("Failed to submit empty buffer #%i, received status: %i \r\n", i, bufferStatus);
            return bufferStatus;
        }
    }

    return kStatus_Success;
}

 

After retrieving this frame we then use PXP to convert it RGB565 which then gets dumped to a file on an SD card (raw data). I’ve attached an example of the output below (with the params w=1280, h=720, color=rgb565, alpha=none). See the below code for an example of the frame retrieving:

#define PXP_OUTPUT_BUFFER_BPP 2

void PXP_PerformCameraBufferTransformation(cam_buffer_info_t *input, pxp_transform_output_info_t *output) {
    pxp_ps_buffer_config_t inputConfig = {
        .pixelFormat = input->colorFormat,
        .swapByte = false,
        .bufferAddrU = 0U,
        .bufferAddrV = 0U,
        .pitchBytes = input->bpp * input->width
    };

    pxp_output_buffer_config_t outputConfig = {
        .pixelFormat = output->desiredFormat,
        .interlacedMode = kPXP_OutputProgressive,
        .buffer1Addr = 0U,
        .pitchBytes = output->bpp * input->width,
        .width = input->width,
        .height = input->height,
    };

    PXP_PRINTF("Created both configs \r\n");

    if(g_rotateFrame) {
        outputConfig.width = input->height;
        outputConfig.height = input->width;
    }else {
        outputConfig.width = input->width;
        outputConfig.height = input->height;
    }

    PXP_PRINTF("Configuring PXP for transform \r\n");
    PXP_SetProcessSurfaceBackGroundColor(STK_PXP, 0);

    if(g_rotateFrame) {
        PXP_SetRotateConfig(STK_PXP, kPXP_RotateOutputBuffer, kPXP_Rotate90, kPXP_FlipDisable);
        PXP_SetProcessSurfaceScaler(STK_PXP, input->width, input->height, input->height, input->width);
    }else {
        PXP_PRINTF("Do not rotate \r\n");
        PXP_SetProcessSurfaceScaler(STK_PXP, input->width, input->height, input->width, input->height);
    }

    PXP_PRINTF("Define Input Buffer \r\n");
    inputConfig.bufferAddr = input->bufferAddress;
    PXP_SetProcessSurfaceBufferConfig(STK_PXP, &inputConfig);

    PXP_PRINTF("Define Output Buffer \r\n");
    outputConfig.buffer0Addr = output->outputAddress;
    PXP_SetOutputBufferConfig(STK_PXP, &outputConfig);

    PXP_PRINTF("Start PXP \r\n");
    PXP_Start(STK_PXP);

    while(!(kPXP_CompleteFlag & PXP_GetStatusFlags(STK_PXP))) {
        PXP_PRINTF("Waiting for PXP to finish \r\n");
    }

    PXP_PRINTF("PXP Finished \r\n");

    PXP_ClearStatusFlags(STK_PXP, kPXP_CompleteFlag);
    PXP_PRINTF("Cleared status flags \r\n");
}

void CameraTestTask(void *pvParameters) {
	uint32_t startTime = xTaskGetTickCount();
	uint32_t receivedFrameAddr;

	PRINTF("Waiting for full buffer \r\n");
	while (kStatus_Success != CAMERA_RECEIVER_GetFullBuffer(&cameraReceiver, &receivedFrameAddr)) { }
	
	PRINTF("Frame Addr: 0x%x", receivedFrameAddr);

	uint32_t midTime = xTaskGetTickCount();
	PRINTF("Time spent retrieving frames: %i\r\n", (midTime - startTime));

	PRINTF("Got all buffers necessary, moving forward...\r\n");

	uint32_t startPXPTime = OSA_TimeGetMsec();

	cam_buffer_info_t inputBufferInfo = {
		.width = CAMERA_FRAME_WIDTH,
		.height = CAMERA_FRAME_HEIGHT,
		.bpp = CAMERA_BUFFER_BPP,
		.bufferAddress = receivedFrameAddr,
		.colorFormat = kPXP_PsPixelFormatRGB888,
	};

	void *outputBuffAddress = outputBuffer[0];
    
	pxp_transform_output_info_t outputBufferInfo = {
		.outputAddress = (uint32_t)outputBuffAddress,
		.bpp = PXP_OUTPUT_BUFFER_BPP,
		.desiredFormat = kPXP_OutputPixelFormatRGB565,
	};

	PXP_PerformCameraBufferTransformation(&inputBufferInfo, &outputBufferInfo);

	uint32_t finishPXPTime = OSA_TimeGetMsec();

	PRINTF("PXP Time (ms): %i\r\n", (finishPXPTime - startPXPTime));

	FIL file;
	char *fileName;
	fileName = (char *) pvParameters;
	PRINTF("Opening file %s\r\n", fileName);

	if(f_open(&file, fileName, (FA_WRITE | FA_CREATE_ALWAYS)) != FR_OK) {
		PRINTF("Failed to open file\r\n");
		(void)CAMERA_RECEIVER_SubmitEmptyBuffer(&cameraReceiver, (uint32_t)receivedFrameAddr);
		vTaskSuspend(NULL);
		return;
	}

	PRINTF("Starting Write\r\n");

	f_write(&file, outputBuffer[0], sizeof(outputBuffer[0]), NULL);

	f_close(&file);
	PRINTF("Written to and close file \r\n");

	CAMERA_RECEIVER_SubmitEmptyBuffer(&cameraReceiver, (uint32_t)receivedFrameAddr);
	PRINTF("Destroyed all structs and resubmitted empty buffers \r\n");

    uint32_t endTime = xTaskGetTickCount();
    PRINTF("Total Time Taken: %i \r\n", endTime - startTime);
    PRINTF("Total Time (ms) %i\r\n", (endTime-startTime)*portTICK_RATE_MS);

	vTaskSuspend(NULL);
}

 

Any ideas as to what could be causing this issue? We’ve tried different colour and camera configurations with no luck. 

 

Thanks,

Jon

Tags (3)
0 Kudos
Reply
1 Reply

544 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @JonMcLeanSMC ,

It seems PXP is useless in your application. You needn't rotate and stretch. You can save picture data from camera directly. If you don't perform XRGB888 to RGB565, doesn't the color correct?

 

Regards,

Jing

 

Regards,

Jing

0 Kudos
Reply