diff --git a/sw/airborne/boards/bebop/video.c b/sw/airborne/boards/bebop/video.c index 47524f0e0ec..fbee4ce24d4 100644 --- a/sw/airborne/boards/bebop/video.c +++ b/sw/airborne/boards/bebop/video.c @@ -126,18 +126,42 @@ void mt9v117_init(void) _write(fd_i2c, "\x09\x82\x00\x01", 4); _write(fd_i2c, "\x09\x8a\x70\x00", 4); - _write(fd_i2c, "\xf0\x00\x72\xcf\xff\x00\x3e\xd0\x92\x00\x71\xcf\xff\xff\xf2\x18\xb1\x10\x92\x05\xb1\x11\x92\x04\xb1\x12\x70\xcf\xff\x00\x30\xc0\x90\x00\x7f\xe0\xb1\x13\x70\xcf\xff\xff\xe7\x1c\x88\x36\x09\x0f\x00\xb3", 50); - _write(fd_i2c, "\xf0\x30\x69\x13\xe1\x80\xd8\x08\x20\xca\x03\x22\x71\xcf\xff\xff\xe5\x68\x91\x35\x22\x0a\x1f\x80\xff\xff\xf2\x18\x29\x05\x00\x3e\x12\x22\x11\x01\x21\x04\x0f\x81\x00\x00\xff\xf0\x21\x8c\xf0\x10\x1a\x22", 50); - _write(fd_i2c, "\xf0\x60\x10\x44\x12\x20\x11\x02\xf7\x87\x22\x4f\x03\x83\x1a\x20\x10\xc4\xf0\x09\xba\xae\x7b\x50\x1a\x20\x10\x84\x21\x45\x01\xc1\x1a\x22\x10\x44\x70\xcf\xff\x00\x3e\xd0\xb0\x60\xb0\x25\x7e\xe0\x78\xe0", 50); - _write(fd_i2c, "\xf0\x90\x71\xcf\xff\xff\xf2\x18\x91\x12\x72\xcf\xff\xff\xe7\x1c\x8a\x57\x20\x04\x0f\x80\x00\x00\xff\xf0\xe2\x80\x20\xc5\x01\x61\x20\xc5\x03\x22\xb1\x12\x71\xcf\xff\x00\x3e\xd0\xb1\x04\x7e\xe0\x78\xe0", 50); - _write(fd_i2c, "\xf0\xc0\x70\xcf\xff\xff\xe7\x1c\x88\x57\x71\xcf\xff\xff\xf2\x18\x91\x13\xea\x84\xb8\xa9\x78\x10\xf0\x03\xb8\x89\xb8\x8c\xb1\x13\x71\xcf\xff\x00\x30\xc0\xb1\x00\x7e\xe0\xc0\xf1\x09\x1e\x03\xc0\xc1\xa1", 50); - _write(fd_i2c, "\xf0\xf0\x75\x08\x76\x28\x77\x48\xc2\x40\xd8\x20\x71\xcf\x00\x03\x20\x67\xda\x02\x08\xae\x03\xa0\x73\xc9\x0e\x25\x13\xc0\x0b\x5e\x01\x60\xd8\x06\xff\xbc\x0c\xce\x01\x00\xd8\x00\xb8\x9e\x0e\x5a\x03\x20", 50); - _write(fd_i2c, "\xf1\x20\xd9\x01\xd8\x00\xb8\x9e\x0e\xb6\x03\x20\xd9\x01\x8d\x14\x08\x17\x01\x91\x8d\x16\xe8\x07\x0b\x36\x01\x60\xd8\x07\x0b\x52\x01\x60\xd8\x11\x8d\x14\xe0\x87\xd8\x00\x20\xca\x02\x62\x00\xc9\x03\xe0", 50); - _write(fd_i2c, "\xf1\x50\xc0\xa1\x78\xe0\xc0\xf1\x08\xb2\x03\xc0\x76\xcf\xff\xff\xe5\x40\x75\xcf\xff\xff\xe5\x68\x95\x17\x96\x40\x77\xcf\xff\xff\xe5\x42\x95\x38\x0a\x0d\x00\x01\x97\x40\x0a\x11\x00\x40\x0b\x0a\x01\x00", 50); - _write(fd_i2c, "\xf1\x80\x95\x17\xb6\x00\x95\x18\xb7\x00\x76\xcf\xff\xff\xe5\x44\x96\x20\x95\x15\x08\x13\x00\x40\x0e\x1e\x01\x20\xd9\x00\x95\x15\xb6\x00\xff\xa1\x75\xcf\xff\xff\xe7\x1c\x77\xcf\xff\xff\xe5\x46\x97\x40", 50); - _write(fd_i2c, "\xf1\xb0\x8d\x16\x76\xcf\xff\xff\xe5\x48\x8d\x37\x08\x0d\x00\x81\x96\x40\x09\x15\x00\x80\x0f\xd6\x01\x00\x8d\x16\xb7\x00\x8d\x17\xb6\x00\xff\xb0\xff\xbc\x00\x41\x03\xc0\xc0\xf1\x0d\x9e\x01\x00\xe8\x04", 50); - _write(fd_i2c, "\xf1\xe0\xff\x88\xf0\x0a\x0d\x6a\x01\x00\x0d\x8e\x01\x00\xe8\x7e\xff\x85\x0d\x72\x01\x00\xff\x8c\xff\xa7\xff\xb2\xd8\x00\x73\xcf\xff\xff\xf2\x40\x23\x15\x00\x01\x81\x41\xe0\x02\x81\x20\x08\xf7\x81\x34", 50); - _write(fd_i2c, "\xf2\x10\xa1\x40\xd8\x00\xc0\xd1\x7e\xe0\x53\x51\x30\x34\x20\x6f\x6e\x5f\x73\x74\x61\x72\x74\x5f\x73\x74\x72\x65\x61\x6d\x69\x6e\x67\x20\x25\x64\x20\x25\x64\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 50); + _write(fd_i2c, + "\xf0\x00\x72\xcf\xff\x00\x3e\xd0\x92\x00\x71\xcf\xff\xff\xf2\x18\xb1\x10\x92\x05\xb1\x11\x92\x04\xb1\x12\x70\xcf\xff\x00\x30\xc0\x90\x00\x7f\xe0\xb1\x13\x70\xcf\xff\xff\xe7\x1c\x88\x36\x09\x0f\x00\xb3", + 50); + _write(fd_i2c, + "\xf0\x30\x69\x13\xe1\x80\xd8\x08\x20\xca\x03\x22\x71\xcf\xff\xff\xe5\x68\x91\x35\x22\x0a\x1f\x80\xff\xff\xf2\x18\x29\x05\x00\x3e\x12\x22\x11\x01\x21\x04\x0f\x81\x00\x00\xff\xf0\x21\x8c\xf0\x10\x1a\x22", + 50); + _write(fd_i2c, + "\xf0\x60\x10\x44\x12\x20\x11\x02\xf7\x87\x22\x4f\x03\x83\x1a\x20\x10\xc4\xf0\x09\xba\xae\x7b\x50\x1a\x20\x10\x84\x21\x45\x01\xc1\x1a\x22\x10\x44\x70\xcf\xff\x00\x3e\xd0\xb0\x60\xb0\x25\x7e\xe0\x78\xe0", + 50); + _write(fd_i2c, + "\xf0\x90\x71\xcf\xff\xff\xf2\x18\x91\x12\x72\xcf\xff\xff\xe7\x1c\x8a\x57\x20\x04\x0f\x80\x00\x00\xff\xf0\xe2\x80\x20\xc5\x01\x61\x20\xc5\x03\x22\xb1\x12\x71\xcf\xff\x00\x3e\xd0\xb1\x04\x7e\xe0\x78\xe0", + 50); + _write(fd_i2c, + "\xf0\xc0\x70\xcf\xff\xff\xe7\x1c\x88\x57\x71\xcf\xff\xff\xf2\x18\x91\x13\xea\x84\xb8\xa9\x78\x10\xf0\x03\xb8\x89\xb8\x8c\xb1\x13\x71\xcf\xff\x00\x30\xc0\xb1\x00\x7e\xe0\xc0\xf1\x09\x1e\x03\xc0\xc1\xa1", + 50); + _write(fd_i2c, + "\xf0\xf0\x75\x08\x76\x28\x77\x48\xc2\x40\xd8\x20\x71\xcf\x00\x03\x20\x67\xda\x02\x08\xae\x03\xa0\x73\xc9\x0e\x25\x13\xc0\x0b\x5e\x01\x60\xd8\x06\xff\xbc\x0c\xce\x01\x00\xd8\x00\xb8\x9e\x0e\x5a\x03\x20", + 50); + _write(fd_i2c, + "\xf1\x20\xd9\x01\xd8\x00\xb8\x9e\x0e\xb6\x03\x20\xd9\x01\x8d\x14\x08\x17\x01\x91\x8d\x16\xe8\x07\x0b\x36\x01\x60\xd8\x07\x0b\x52\x01\x60\xd8\x11\x8d\x14\xe0\x87\xd8\x00\x20\xca\x02\x62\x00\xc9\x03\xe0", + 50); + _write(fd_i2c, + "\xf1\x50\xc0\xa1\x78\xe0\xc0\xf1\x08\xb2\x03\xc0\x76\xcf\xff\xff\xe5\x40\x75\xcf\xff\xff\xe5\x68\x95\x17\x96\x40\x77\xcf\xff\xff\xe5\x42\x95\x38\x0a\x0d\x00\x01\x97\x40\x0a\x11\x00\x40\x0b\x0a\x01\x00", + 50); + _write(fd_i2c, + "\xf1\x80\x95\x17\xb6\x00\x95\x18\xb7\x00\x76\xcf\xff\xff\xe5\x44\x96\x20\x95\x15\x08\x13\x00\x40\x0e\x1e\x01\x20\xd9\x00\x95\x15\xb6\x00\xff\xa1\x75\xcf\xff\xff\xe7\x1c\x77\xcf\xff\xff\xe5\x46\x97\x40", + 50); + _write(fd_i2c, + "\xf1\xb0\x8d\x16\x76\xcf\xff\xff\xe5\x48\x8d\x37\x08\x0d\x00\x81\x96\x40\x09\x15\x00\x80\x0f\xd6\x01\x00\x8d\x16\xb7\x00\x8d\x17\xb6\x00\xff\xb0\xff\xbc\x00\x41\x03\xc0\xc0\xf1\x0d\x9e\x01\x00\xe8\x04", + 50); + _write(fd_i2c, + "\xf1\xe0\xff\x88\xf0\x0a\x0d\x6a\x01\x00\x0d\x8e\x01\x00\xe8\x7e\xff\x85\x0d\x72\x01\x00\xff\x8c\xff\xa7\xff\xb2\xd8\x00\x73\xcf\xff\xff\xf2\x40\x23\x15\x00\x01\x81\x41\xe0\x02\x81\x20\x08\xf7\x81\x34", + 50); + _write(fd_i2c, + "\xf2\x10\xa1\x40\xd8\x00\xc0\xd1\x7e\xe0\x53\x51\x30\x34\x20\x6f\x6e\x5f\x73\x74\x61\x72\x74\x5f\x73\x74\x72\x65\x61\x6d\x69\x6e\x67\x20\x25\x64\x20\x25\x64\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 50); _write(fd_i2c, "\xf2\x40\xff\xff\xe8\x28\xff\xff\xf0\xe8\xff\xff\xe8\x08\xff\xff\xf1\x54", 18); _write(fd_i2c, "\x09\x8e\x00\x00", 4); _write(fd_i2c, "\xe0\x00\x05\xd8", 4); @@ -233,7 +257,7 @@ uint16_t mt9f002_read_reg16(uint16_t reg); void mt9f002_open(void) { mt9f002_i2c_port = open("/dev/i2c-0", O_RDWR); - if(mt9f002_i2c_port < 0) { + if (mt9f002_i2c_port < 0) { printf("mt9f002_open"); // exit(1); } @@ -246,7 +270,7 @@ void mt9f002_close(void) void mt9f002_set_address(uint8_t address) { - if(ioctl(mt9f002_i2c_port, I2C_SLAVE_FORCE, address) < 0) { + if (ioctl(mt9f002_i2c_port, I2C_SLAVE_FORCE, address) < 0) { printf("mt9f002_set_address"); // exit(1); } @@ -262,7 +286,7 @@ void mt9f002_write_reg8(uint16_t reg, uint8_t value) data[1] = (uint8_t)reg & 0xFF; data[2] = value; // if(i2c_smbus_write_byte_data(mt9f002_i2c_port,reg,value) < 0) { - if(write(mt9f002_i2c_port, data, 3) < 0) { + if (write(mt9f002_i2c_port, data, 3) < 0) { printf("mt9f002_write_reg8"); // exit(1); } @@ -282,7 +306,7 @@ void mt9f002_write_reg16(uint16_t reg, uint16_t value) data[1] = (uint8_t)reg & 0xFF; data[2] = (uint8_t)(value >> 8); data[3] = value & 0xFF; - if(write(mt9f002_i2c_port, data, 4) < 0) { + if (write(mt9f002_i2c_port, data, 4) < 0) { printf("mt9f002_write_reg16"); // exit(1); } @@ -336,153 +360,153 @@ void mt9f002_init(void) mt9f002_write_reg8(MT9F002_MODE_SELECT, 0x00); /* Change registers */ - mt9f002_write_reg16(MT9F002_P_GR_P0Q0,0); - mt9f002_write_reg16(MT9F002_P_GR_P0Q2,0); - mt9f002_write_reg16(MT9F002_P_GR_P0Q3,0); - mt9f002_write_reg16(MT9F002_P_GR_P0Q4,0); - mt9f002_write_reg16(MT9F002_P_RD_P0Q0,0); - mt9f002_write_reg16(MT9F002_P_RD_P0Q1,0); - mt9f002_write_reg16(MT9F002_P_RD_P0Q2,0); - mt9f002_write_reg16(MT9F002_P_RD_P0Q3,0); - mt9f002_write_reg16(MT9F002_P_RD_P0Q4,0); - mt9f002_write_reg16(MT9F002_P_BL_P0Q0,0); - mt9f002_write_reg16(MT9F002_P_BL_P0Q1,0); - mt9f002_write_reg16(MT9F002_P_BL_P0Q2,0); - mt9f002_write_reg16(MT9F002_P_BL_P0Q3,0); - mt9f002_write_reg16(MT9F002_P_BL_P0Q4,0); - mt9f002_write_reg16(MT9F002_P_GB_P0Q0,0); - mt9f002_write_reg16(MT9F002_P_GB_P0Q1,0); - mt9f002_write_reg16(MT9F002_P_GB_P0Q2,0); - mt9f002_write_reg16(MT9F002_P_GB_P0Q3,0); - mt9f002_write_reg16(MT9F002_P_GB_P0Q4,0); - mt9f002_write_reg16(MT9F002_P_GR_P1Q0,0); - mt9f002_write_reg16(MT9F002_P_GR_P1Q1,0); - mt9f002_write_reg16(MT9F002_P_GR_P1Q2,0); - mt9f002_write_reg16(MT9F002_P_GR_P1Q3,0); - mt9f002_write_reg16(MT9F002_P_GR_P1Q4,0); - mt9f002_write_reg16(MT9F002_P_RD_P1Q0,0); - mt9f002_write_reg16(MT9F002_P_RD_P1Q1,0); - mt9f002_write_reg16(MT9F002_P_RD_P1Q2,0); - mt9f002_write_reg16(MT9F002_P_RD_P1Q3,0); - mt9f002_write_reg16(MT9F002_P_RD_P1Q4,0); - mt9f002_write_reg16(MT9F002_P_BL_P1Q0,0); - mt9f002_write_reg16(MT9F002_P_BL_P1Q1,0); - mt9f002_write_reg16(MT9F002_P_BL_P1Q2,0); - mt9f002_write_reg16(MT9F002_P_BL_P1Q3,0); - mt9f002_write_reg16(MT9F002_P_BL_P1Q4,0); - mt9f002_write_reg16(MT9F002_P_GB_P1Q0,0); - mt9f002_write_reg16(MT9F002_P_GB_P1Q1,0); - mt9f002_write_reg16(MT9F002_P_GB_P1Q2,0); - mt9f002_write_reg16(MT9F002_P_GB_P1Q3,0); - mt9f002_write_reg16(MT9F002_P_GB_P1Q4,0); - mt9f002_write_reg16(MT9F002_P_GR_P2Q0,0); - mt9f002_write_reg16(MT9F002_P_GR_P2Q1,0); - mt9f002_write_reg16(MT9F002_P_GR_P2Q2,0); - mt9f002_write_reg16(MT9F002_P_GR_P2Q3,0); - mt9f002_write_reg16(MT9F002_P_GR_P2Q4,0); - mt9f002_write_reg16(MT9F002_P_RD_P2Q0,0); - mt9f002_write_reg16(MT9F002_P_RD_P2Q1,0); - mt9f002_write_reg16(MT9F002_P_RD_P2Q2,0); - mt9f002_write_reg16(MT9F002_P_RD_P2Q3,0); - mt9f002_write_reg16(MT9F002_P_RD_P2Q4,0); - mt9f002_write_reg16(MT9F002_P_BL_P2Q0,0); - mt9f002_write_reg16(MT9F002_P_BL_P2Q1,0); - mt9f002_write_reg16(MT9F002_P_BL_P2Q2,0); - mt9f002_write_reg16(MT9F002_P_BL_P2Q3,0); - mt9f002_write_reg16(MT9F002_P_BL_P2Q4,0); - mt9f002_write_reg16(MT9F002_P_GB_P2Q0,0); - mt9f002_write_reg16(MT9F002_P_GB_P2Q1,0); - mt9f002_write_reg16(MT9F002_P_GB_P2Q2,0); - mt9f002_write_reg16(MT9F002_P_GB_P2Q3,0); - mt9f002_write_reg16(MT9F002_P_GB_P2Q4,0); - mt9f002_write_reg16(MT9F002_P_GR_P3Q0,0); - mt9f002_write_reg16(MT9F002_P_GR_P3Q1,0); - mt9f002_write_reg16(MT9F002_P_GR_P3Q2,0); - mt9f002_write_reg16(MT9F002_P_GR_P3Q3,0); - mt9f002_write_reg16(MT9F002_P_GR_P3Q4,0); - mt9f002_write_reg16(MT9F002_P_RD_P3Q0,0); - mt9f002_write_reg16(MT9F002_P_RD_P3Q1,0); - mt9f002_write_reg16(MT9F002_P_RD_P3Q2,0); - mt9f002_write_reg16(MT9F002_P_RD_P3Q3,0); - mt9f002_write_reg16(MT9F002_P_RD_P3Q4,0); - mt9f002_write_reg16(MT9F002_P_BL_P3Q0,0); - mt9f002_write_reg16(MT9F002_P_BL_P3Q1,0); - mt9f002_write_reg16(MT9F002_P_BL_P3Q2,0); - mt9f002_write_reg16(MT9F002_P_BL_P3Q3,0); - mt9f002_write_reg16(MT9F002_P_BL_P3Q4,0); - mt9f002_write_reg16(MT9F002_P_GB_P3Q0,0); - mt9f002_write_reg16(MT9F002_P_GB_P3Q1,0); - mt9f002_write_reg16(MT9F002_P_GB_P3Q2,0); - mt9f002_write_reg16(MT9F002_P_GB_P3Q3,0); - mt9f002_write_reg16(MT9F002_P_GB_P3Q4,0); - mt9f002_write_reg16(MT9F002_P_GR_P4Q0,0); - mt9f002_write_reg16(MT9F002_P_GR_P4Q1,0); - mt9f002_write_reg16(MT9F002_P_GR_P4Q2,0); - mt9f002_write_reg16(MT9F002_P_GR_P4Q3,0); - mt9f002_write_reg16(MT9F002_P_GR_P4Q4,0); - mt9f002_write_reg16(MT9F002_P_RD_P4Q0,0); - mt9f002_write_reg16(MT9F002_P_RD_P4Q1,0); - mt9f002_write_reg16(MT9F002_P_RD_P4Q2,0); - mt9f002_write_reg16(MT9F002_P_RD_P4Q3,0); - mt9f002_write_reg16(MT9F002_P_RD_P4Q4,0); - mt9f002_write_reg16(MT9F002_P_BL_P4Q0,0); - mt9f002_write_reg16(MT9F002_P_BL_P4Q1,0); - mt9f002_write_reg16(MT9F002_P_BL_P4Q2,0); - mt9f002_write_reg16(MT9F002_P_BL_P4Q3,0); - mt9f002_write_reg16(MT9F002_P_BL_P4Q4,0); - mt9f002_write_reg16(MT9F002_P_GB_P4Q0,0); - mt9f002_write_reg16(MT9F002_P_GB_P4Q1,0); - mt9f002_write_reg16(MT9F002_P_GB_P4Q2,0); - mt9f002_write_reg16(MT9F002_P_GB_P4Q3,0); - mt9f002_write_reg16(MT9F002_P_GB_P4Q4,0); - - mt9f002_write_reg16(MT9F002_GREEN1_GAIN,4176); - mt9f002_write_reg16(MT9F002_BLUE_GAIN,4176); - mt9f002_write_reg16(MT9F002_RED_GAIN,4176); - mt9f002_write_reg16(MT9F002_GREEN2_GAIN,4176); - mt9f002_write_reg16(MT9F002_GLOBAL_GAIN,4176); - mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GLOBAL,10); - mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GREENR,10); - mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_RED,10); - mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_BLUE,10); - mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GREENB,10); - mt9f002_write_reg16(MT9F002_CALIB_GREEN1_ASC1,4224); - mt9f002_write_reg16(MT9F002_CALIB_BLUE_ASC1,4224); - mt9f002_write_reg16(MT9F002_CALIB_RED_ASC1,4224); - mt9f002_write_reg16(MT9F002_CALIB_GREEN2_ASC1,4224); - mt9f002_write_reg16(MT9F002_CALIB_GREEN1,4224); - mt9f002_write_reg16(MT9F002_CALIB_BLUE,4224); - mt9f002_write_reg16(MT9F002_CALIB_RED,4224); - mt9f002_write_reg16(MT9F002_CALIB_GREEN2,4224); - mt9f002_write_reg16(MT9F002_POLY_ORIGIN_C,0); - mt9f002_write_reg16(MT9F002_POLY_ORIGIN_R,0); - mt9f002_write_reg16(MT9F002_P_GR_Q5,0); - mt9f002_write_reg16(MT9F002_P_RD_Q5,0); - mt9f002_write_reg16(MT9F002_P_BL_Q5,0); - mt9f002_write_reg16(MT9F002_P_GB_Q5,0); - mt9f002_write_reg16(MT9F002_DAC_ID_FBIAS,57568); - - mt9f002_write_reg16(MT9F002_FRAME_LENGTH_LINES,3434); - mt9f002_write_reg16(MT9F002_LINE_LENGTH_PCK,2504); - mt9f002_write_reg16(MT9F002_ROW_SPEED,273); - mt9f002_write_reg16(MT9F002_MIPI_TIMING_2,61452); - mt9f002_write_reg16(MT9F002_HISPI_TIMING,0); - - mt9f002_write_reg16(MT9F002_VT_PIX_CLK_DIV,6); - mt9f002_write_reg16(MT9F002_PRE_PLL_CLK_DIV,6); - mt9f002_write_reg16(MT9F002_PLL_MULTIPLIER,165); - mt9f002_write_reg16(MT9F002_OP_PIX_CLK_DIV,12); - - mt9f002_write_reg16(MT9F002_X_ADDR_START_,144); - mt9f002_write_reg16(MT9F002_Y_ADDR_START_,32); - mt9f002_write_reg16(MT9F002_X_ADDR_END_,4527); // 4383 cols - mt9f002_write_reg16(MT9F002_Y_ADDR_END_,3319); // 3287 rows - mt9f002_write_reg16(MT9F002_READ_MODE,0x06E7); - mt9f002_write_reg16(MT9F002_X_ODD_INC,7); - mt9f002_write_reg16(MT9F002_Y_ODD_INC,7); // Sample 1, skip 7 -> /8 - - mt9f002_write_reg16(MT9F002_SCALING_MODE,2); - mt9f002_write_reg16(MT9F002_SCALE_M,48); + mt9f002_write_reg16(MT9F002_P_GR_P0Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P0Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P0Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P0Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q4, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q1, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q4, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q1, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q4, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q1, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q4, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q1, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q4, 0); + + mt9f002_write_reg16(MT9F002_GREEN1_GAIN, 4176); + mt9f002_write_reg16(MT9F002_BLUE_GAIN, 4176); + mt9f002_write_reg16(MT9F002_RED_GAIN, 4176); + mt9f002_write_reg16(MT9F002_GREEN2_GAIN, 4176); + mt9f002_write_reg16(MT9F002_GLOBAL_GAIN, 4176); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GLOBAL, 10); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GREENR, 10); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_RED, 10); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_BLUE, 10); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GREENB, 10); + mt9f002_write_reg16(MT9F002_CALIB_GREEN1_ASC1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_BLUE_ASC1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_RED_ASC1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_GREEN2_ASC1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_GREEN1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_BLUE, 4224); + mt9f002_write_reg16(MT9F002_CALIB_RED, 4224); + mt9f002_write_reg16(MT9F002_CALIB_GREEN2, 4224); + mt9f002_write_reg16(MT9F002_POLY_ORIGIN_C, 0); + mt9f002_write_reg16(MT9F002_POLY_ORIGIN_R, 0); + mt9f002_write_reg16(MT9F002_P_GR_Q5, 0); + mt9f002_write_reg16(MT9F002_P_RD_Q5, 0); + mt9f002_write_reg16(MT9F002_P_BL_Q5, 0); + mt9f002_write_reg16(MT9F002_P_GB_Q5, 0); + mt9f002_write_reg16(MT9F002_DAC_ID_FBIAS, 57568); + + mt9f002_write_reg16(MT9F002_FRAME_LENGTH_LINES, 3434); + mt9f002_write_reg16(MT9F002_LINE_LENGTH_PCK, 2504); + mt9f002_write_reg16(MT9F002_ROW_SPEED, 273); + mt9f002_write_reg16(MT9F002_MIPI_TIMING_2, 61452); + mt9f002_write_reg16(MT9F002_HISPI_TIMING, 0); + + mt9f002_write_reg16(MT9F002_VT_PIX_CLK_DIV, 6); + mt9f002_write_reg16(MT9F002_PRE_PLL_CLK_DIV, 6); + mt9f002_write_reg16(MT9F002_PLL_MULTIPLIER, 165); + mt9f002_write_reg16(MT9F002_OP_PIX_CLK_DIV, 12); + + mt9f002_write_reg16(MT9F002_X_ADDR_START_, 500); + mt9f002_write_reg16(MT9F002_Y_ADDR_START_, 32); + mt9f002_write_reg16(MT9F002_X_ADDR_END_, 4527); // 4383 cols + mt9f002_write_reg16(MT9F002_Y_ADDR_END_, 3319); // 3287 rows + mt9f002_write_reg16(MT9F002_READ_MODE, 0x06E7); + mt9f002_write_reg16(MT9F002_X_ODD_INC, 3); + mt9f002_write_reg16(MT9F002_Y_ODD_INC, 3); // Sample 1, skip 7 -> /8 + + mt9f002_write_reg16(MT9F002_SCALING_MODE, 2); + mt9f002_write_reg16(MT9F002_SCALE_M, 48); /* Stream mode */ diff --git a/sw/airborne/modules/computer_vision/bebop_front_camera.c b/sw/airborne/modules/computer_vision/bebop_front_camera.c index 4e16bdca4ea..219fdd768f5 100644 --- a/sw/airborne/modules/computer_vision/bebop_front_camera.c +++ b/sw/airborne/modules/computer_vision/bebop_front_camera.c @@ -37,7 +37,7 @@ // Video #include "lib/v4l/v4l2.h" #include "lib/vision/image.h" -#include "lib/vision/demosaic.h" +#include "lib/vision/bayern.h" #include "lib/encoding/jpeg.h" #include "lib/encoding/rtp.h" #include "udp_socket.h" @@ -45,20 +45,10 @@ // Threaded computer vision #include -// 4383 cols -> 2191.5 -// 3287 rows -> 1643 - -// Open: 1408, 2112 - - -#define MT9F002_GRAB_ROWS 1408 -#define MT9F002_RAW_ROWS (MT9F002_GRAB_ROWS*2) -#define MT9F002_RAW_COLS 2112 -#define MT9F002_ROWS 364 -#define MT9F002_COLS 274 -#define MT9F002_RAW_IMAGE_SIZE 2*274*364 -#define MT9F002_GRAY_IMAGE_SIZE 274*364 - +#define MT9F002_WIDTH 1408 +#define MT9F002_HEIGHT 2112 +#define BEBOP_FRONT_CAMERA_WIDTH 272 +#define BEBOP_FRONT_CAMERA_HEIGHT 272 // The place where the shots are saved (without slash on the end) #ifndef BEBOP_FRONT_CAMERA_SHOT_PATH @@ -80,7 +70,7 @@ struct viewvideo_t bebop_front_camera = { void bebop_front_camera_take_shot(bool_t take) { - bebop_front_camera.take_shot = TRUE; + bebop_front_camera.take_shot = TRUE; } /** * Handles all the video streaming and saving of the image shots @@ -89,19 +79,16 @@ void bebop_front_camera_take_shot(bool_t take) static void *bebop_front_camera_thread(void *data __attribute__((unused))) { struct UdpSocket video_sock; - udp_socket_create(&video_sock, STRINGIFY(BEBOP_FRONT_CAMERA_HOST), BEBOP_FRONT_CAMERA_PORT_OUT, -1, BEBOP_FRONT_CAMERA_BROADCAST); + udp_socket_create(&video_sock, STRINGIFY(BEBOP_FRONT_CAMERA_HOST), BEBOP_FRONT_CAMERA_PORT_OUT, -1, + BEBOP_FRONT_CAMERA_BROADCAST); // Create the JPEG encoded image struct image_t img_jpeg; - image_create(&img_jpeg, MT9F002_ROWS, MT9F002_COLS, IMAGE_JPEG); - - // Create the Gray encoded image - struct image_t img_gray; - image_create(&img_gray, MT9F002_ROWS, MT9F002_COLS, IMAGE_GRAYSCALE); + image_create(&img_jpeg, BEBOP_FRONT_CAMERA_WIDTH, BEBOP_FRONT_CAMERA_HEIGHT, IMAGE_JPEG); // Create the Color image struct image_t img_color; - image_create(&img_color, MT9F002_ROWS, MT9F002_COLS, IMAGE_YUV422); + image_create(&img_color, BEBOP_FRONT_CAMERA_WIDTH, BEBOP_FRONT_CAMERA_HEIGHT, IMAGE_YUV422); // Start the streaming of the V4L2 device if (!v4l2_start_capture(bebop_front_camera.dev)) { @@ -116,34 +103,14 @@ static void *bebop_front_camera_thread(void *data __attribute__((unused))) struct image_t img; v4l2_image_get(bebop_front_camera.dev, &img); - - // Crop - uint8_t img_buf[MT9F002_RAW_IMAGE_SIZE]; - for (int i = 0; i < MT9F002_COLS; i++) { - memcpy(img_buf + i * 2 * MT9F002_ROWS, ((uint8_t *)img.buf) + i * img.w * 2, MT9F002_ROWS * 2); - } - - // Demosaic BAYERN - uint16_t *img_buf_u16 = (uint16_t *)img_buf; - BilinearDemosaicGray(&img_gray, img_buf_u16, 0, 1); - + BayernToYUV(&img, &img_color, 0, 0); if (bebop_front_camera.take_shot) { // Save the image - bebop_front_camera_save_shot(&img_gray,&img_jpeg,&img); + bebop_front_camera_save_shot(&img_color, &img_jpeg, &img); bebop_front_camera.take_shot = FALSE; } - // Convert Gray to YUV422 for Jpeg compression - for (int y = 0; y < img_color.h; y++) { - for (int x = 0; x < img_color.w; x++) { - int i = x + y * img_color.w; - ((uint8_t *)img_color.buf)[i * 2 + 0] = 127; - ((uint8_t *)img_color.buf)[i * 2 + 1] = ((uint8_t *)img_gray.buf)[i]; - } - } - - jpeg_encode_image(&img_color, &img_jpeg, 80, 0); // Send image with RTP @@ -170,13 +137,13 @@ static void *bebop_front_camera_thread(void *data __attribute__((unused))) void bebop_front_camera_init(void) { // Initialize the V4L2 subdevice (TODO: fix hardcoded path, which and code) - if (!v4l2_init_subdev("/dev/v4l-subdev1", 0, 0, V4L2_MBUS_FMT_SGBRG10_1X10, MT9F002_GRAB_ROWS, MT9F002_RAW_COLS)) { + if (!v4l2_init_subdev("/dev/v4l-subdev1", 0, 0, V4L2_MBUS_FMT_SGBRG10_1X10, MT9F002_WIDTH, MT9F002_HEIGHT)) { printf("[bebop_front_camera] Could not initialize the v4l-subdev1 subdevice.\n"); return; } // Initialize the V4L2 device - bebop_front_camera.dev = v4l2_init("/dev/video1", MT9F002_GRAB_ROWS, MT9F002_RAW_COLS, 10, V4L2_PIX_FMT_SGBRG10); + bebop_front_camera.dev = v4l2_init("/dev/video1", MT9F002_WIDTH, MT9F002_HEIGHT, 10, V4L2_PIX_FMT_SGBRG10); if (bebop_front_camera.dev == NULL) { printf("[bebop_front_camera] Could not initialize the /dev/video1 V4L2 device.\n"); return; @@ -248,7 +215,7 @@ static void bebop_front_camera_save_shot(struct image_t *img_gray, struct image_ // Save it to the file and close it char pgm_header[] = "P5\n364 264\n255\n"; fwrite(pgm_header, sizeof(char), 15, fp); - fwrite(img_gray->buf, sizeof(uint8_t), MT9F002_GRAY_IMAGE_SIZE, fp); + fwrite(img_gray->buf, sizeof(uint8_t), img_gray->buf_size, fp); fclose(fp); // JPEG diff --git a/sw/airborne/modules/computer_vision/lib/vision/bayern.h b/sw/airborne/modules/computer_vision/lib/vision/bayern.h index 4236b1a8069..0ee9cf03e39 100644 --- a/sw/airborne/modules/computer_vision/lib/vision/bayern.h +++ b/sw/airborne/modules/computer_vision/lib/vision/bayern.h @@ -1,47 +1,102 @@ +/* + * Copyright (C) 2012-2014 The Paparazzi Community + * 2015 Freek van Tienen + * + * This file is part of Paparazzi. + * + * Paparazzi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * Paparazzi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with paparazzi; see the file COPYING. If not, see + * . + * + */ + +/** + * @file modules/computer_vision/lib/vision/bayern.c + */ + #ifndef BAYERN_H #define BAYERN_H +#include "lib/vision/image.h" + +static inline uint8_t clip(uint16_t x) +{ + if (x < 0) { + return 0; + } + if (x > 255) { + return 255; + } + return (uint8_t) x; +} + + +void BayernToYUV(struct image_t *Input, struct image_t *out, + int RedX, int RedY); + + /** - * @brief Bilinear demosaicing - * @param Output pointer to memory to store the demosaiced image - * @param Input the input image as a flattened 2D array - * @param Width, Height the image dimensions - * @param RedX, RedY the coordinates of the upper-rightmost red pixel - * which has a blue pixel next to it and a green underneath + * @brief Decode Bayern Pattern + * @param RedX, RedY the coordinates of the upper-rightmost green pixel + * which has a red pixel next to it and a blue underneath * */ -#include "lib/vision/image.h" +void BayernToYUV(struct image_t *in, struct image_t *out, + int RedX, int RedY) +{ + uint16_t *ii = (uint8_t *) in->buf; + uint8_t *oi = (uint8_t *) out->buf; + int x, y; -void BayernToYUV(struct image_t *out, struct image_t *Input, - int RedX, int RedY); + for (y = 0; y < out->h; y++) { + for (x = 0; x < out->w; x += 2) { + /* RGB Bayern: + * RBRBRBRBRBRBRBRB + * GRGRGRGRGRGRGRGR + */ + int i = 2 * (out->h - y) + RedX; + int j = 2 * x + RedY; + if ((i < in->w) && (j < in->h)) { + uint16_t G1 = ii[i + j * in->w] / 2; + uint16_t R1 = ii[i + j * in->w + 1] / 2; + uint16_t B1 = ii[i + (j + 1) * in->w] / 2; + j += 2; + uint16_t G2 = ii[i + j * in->w] / 2; + uint16_t R2 = ii[i + j * in->w + 1] / 2; + uint16_t B2 = ii[i + (j + 1) * in->w] / 2; -void BayernToYUV(struct image_t *out, struct image_t *Input, - int RedX, int RedY) -{ - int i = 0, x, y; - - int rWidth = out->w - 1; - int rHeight = out->h - 1; - - for (y = RedY; y < rHeight; y+=2) - { - for (x = RedX; x < rWidth; x+=2) - { - /* RGB Bayern: - * RBRBRBRBRBRBRBRB - * GRGRGRGRGRGRGRGR - */ - uint8_t R1 = Input->buf[x+y*Input->w]; - uint8_t B = Input->buf[x+y*Input->w+1]; - uint8_t G = Input->buf[x+(y+1)*Input->w]; - uint8_t R2 = Input->buf[x+(y+1)*Input->w+1]; - - ((uint8_t*)out->buf)[i] = (uint8_t)(GrayPx/256); - - } + uint32_t u, y1, v, y2; + + y1 = (0.256788 * R1 + 0.504129 * G1 + 0.097906 * B1) / 128 + 16; + y2 = (0.256788 * R2 + 0.504129 * G2 + 0.097906 * B2) / 128 + 16; + u = (-0.148223 * (R1 + R2) - 0.290993 * (G1 + G2) + 0.439216 * (B1 + B2)) / 256 + 128; + v = (0.439216 * (R1 + R2) - 0.367788 * (G1 + G2) - 0.071427 * (B1 + B2)) / 256 + 128; + + + oi[(x + y * out->w) * 2] = clip(u); + oi[(x + y * out->w) * 2 + 1] = clip(y1); + oi[(x + y * out->w) * 2 + 2] = clip(v); + oi[(x + y * out->w) * 2 + 3] = clip(y2); + } else { + oi[(x + y * out->w) * 2] = 0; + oi[(x + y * out->w) * 2 + 1] = 0; + oi[(x + y * out->w) * 2 + 2] = 0; + oi[(x + y * out->w) * 2 + 3] = 0; + } } + } } #endif /* BAYERN_H */ diff --git a/sw/airborne/modules/computer_vision/lib/vision/demosaic.h b/sw/airborne/modules/computer_vision/lib/vision/demosaic.h deleted file mode 100644 index 2ba6b6b5e98..00000000000 --- a/sw/airborne/modules/computer_vision/lib/vision/demosaic.h +++ /dev/null @@ -1,172 +0,0 @@ -#ifndef DEMOSAIC_H -#define DEMOSAIC_H - -/** - * @brief Bilinear demosaicing - * @param Output pointer to memory to store the demosaiced image - * @param Input the input image as a flattened 2D array - * @param RedX, RedY the coordinates of the upper-rightmost red pixel - * - * Bilinear demosaicing is considered to be the simplest demosaicing method and - * is used as a baseline for comparing more sophisticated methods. - * - * The Input image is a 2D float array of the input RGB values of size - * Width*Height in row-major order. RedX, RedY are the coordinates of the - * upper-rightmost red pixel to specify the CFA pattern. - */ - -#include "lib/vision/image.h" - -void BilinearDemosaicGray(struct image_t *out, const uint16_t *Input, - int RedX, int RedY); - - -void BilinearDemosaicGray(struct image_t *out, const uint16_t *Input, - int RedX, int RedY) -{ - const int Green = 1 - ((RedX + RedY) & 1); - uint16_t AverageH, AverageV, AverageC, AverageX; - int i, x, y; - - int Width = out->w; - int Height = out->h; - - for (y = 0, i = 0; y < Height; y++) - { - for (x = 0; x < Width; x++, i++) - { - /* The following computes four quantities: - * AverageH: average of the horizontal neighbors - * AverageV: average of the vertical neighbors - * AverageC: average of the axial neighbors - * AverageX: average of the diagonal neighbors - * - * Near a boundary, the average is computed using only those - * samples which are defined in the image. For example on the left - * boundary of the image, the left neighbors are omitted and - * AverageH is simply set to the value of the right neighbor. - */ - if (y == 0) - { - AverageV = Input[i + Width]; - - if (x == 0) - { - AverageH = Input[i + 1]; - AverageC = (Input[i + 1] + Input[i + Width]) / 2; - AverageX = Input[i + 1 + Width]; - } - else if (x < Width - 1) - { - AverageH = (Input[i - 1] + Input[i + 1]) / 2; - AverageC = (Input[i - 1] + Input[i + 1] - + Input[i + Width]) / 3; - AverageX = (Input[i - 1 + Width] - + Input[i + 1 + Width]) / 2; - } - else - { - AverageH = Input[i - 1]; - AverageC = (Input[i - 1] + Input[i + Width]) / 2; - AverageX = Input[i - 1 + Width]; - } - } - else if (y < Height - 1) - { - AverageV = (Input[i - Width] + Input[i + Width]) / 2; - - if (x == 0) - { - AverageH = Input[i + 1]; - AverageC = (Input[i + 1] + - Input[i - Width] + Input[i + Width]) / 3; - AverageX = (Input[i + 1 - Width] - + Input[i + 1 + Width]) / 2; - } - else if (x < Width - 1) - { - AverageH = (Input[i - 1] + Input[i + 1]) / 2; - AverageC = (AverageH + AverageV) / 2; - AverageX = (Input[i - 1 - Width] + Input[i + 1 - Width] - + Input[i - 1 + Width] + Input[i + 1 + Width]) / 4; - } - else - { - AverageH = Input[i - 1]; - AverageC = (Input[i - 1] + - Input[i - Width] + Input[i + Width]) / 3; - AverageX = (Input[i - 1 - Width] - + Input[i - 1 + Width]) / 2; - } - } - else - { - AverageV = Input[i - Width]; - - if (x == 0) - { - AverageH = Input[i + 1]; - AverageC = (Input[i + 1] + Input[i - Width]) / 2; - AverageX = Input[i + 1 - Width]; - } - else if (x < Width - 1) - { - AverageH = (Input[i - 1] + Input[i + 1]) / 2; - AverageC = (Input[i - 1] - + Input[i + 1] + Input[i - Width]) / 3; - AverageX = (Input[i - 1 - Width] - + Input[i + 1 - Width]) / 2; - } - else - { - AverageH = Input[i - 1]; - AverageC = (Input[i - 1] + Input[i - Width]) / 2; - AverageX = Input[i - 1 - Width]; - } - } - - /* Generate grayscale output*/ - float GrayPx = 0; - if (((x + y) & 1) == Green) - { - /* Center pixel is green */ - GrayPx += 0.7152 * (float)(Input[i]); - - if ((y & 1) == RedY) - { - /* Left and right neighbors are red */ - GrayPx += 0.2126 * (float)(AverageH); - GrayPx += 0.0722 * (float)(AverageV); - } - else - { - /* Left and right neighbors are blue */ - GrayPx += 0.2126 * (float)(AverageV); - GrayPx += 0.0722 * (float)(AverageH); - } - } - else - { - GrayPx += 0.7152 * (float)(AverageC); - - if ((y & 1) == RedY) - { - /* Center pixel is red */ - GrayPx += 0.2126 * (float)(Input[i]); - GrayPx += 0.0722 * (float)(AverageX); - } - else - { - /* Center pixel is blue */ - GrayPx += 0.2126 * (float)(AverageX); - GrayPx += 0.0722 * (float)(Input[i]); - } - } - - ((uint8_t*)out->buf)[i] = (uint8_t)(GrayPx/256); - - } - } -} - -#endif /* DEMOSAIC_H */