Merge branch 'dev_extract_rgb_from_bayer' into main

main
Xiao Song 3 years ago
commit d81b47732d

6
.gitignore vendored

@ -56,4 +56,8 @@ tests/test_burst
.vscode/ .vscode/
# VS Settings # VS Settings
CMakeSettings.json CMakeSettings.json
# Xiao local files
debug/

@ -4,10 +4,10 @@ cmake_minimum_required(VERSION 3.0)
project(hdrplus) project(hdrplus)
# set c++ standard # set c++ standard
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -march=native -O3") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -Wall -march=native -O3") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
# make sure we use Release and warn otherwise # make sure we use Release and warn otherwise
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
@ -24,7 +24,7 @@ else()
endif() endif()
# require OpenCV # require OpenCV
find_package( OpenCV 3 REQUIRED ) find_package( OpenCV 4 REQUIRED )
include_directories( BEFORE ${OpenCV_INCLUDE_DIRS} ) include_directories( BEFORE ${OpenCV_INCLUDE_DIRS} )
message(STATUS "Found OpenCV ${OpenCV_INCLUDE_DIRS} ${OpenCV_LIBS}") message(STATUS "Found OpenCV ${OpenCV_INCLUDE_DIRS} ${OpenCV_LIBS}")
@ -37,13 +37,6 @@ message(STATUS "Found LIBRAW_LIBRARY to be ${LIBRAW_LIBRARY}" )
find_package(exiv2 REQUIRED CONFIG NAMES exiv2) find_package(exiv2 REQUIRED CONFIG NAMES exiv2)
message(STATUS "Found Exiv2 and linked") message(STATUS "Found Exiv2 and linked")
if(NOT APPLE)
# The clang compiler (on osx) is somehow much more strict
# than the compilers on ubuntu and so this does not seem
# possible on OSX just yet.
add_definitions( -Werror )
endif()
# library # library
include_directories( include ) include_directories( include )

@ -127,4 +127,84 @@ cv::Mat downsample_nearest_neighbour( cv::Mat src_image )
return dst_image; return dst_image;
} }
template< typename T >
void print_cvmat( cv::Mat image )
{
const T* img_ptr = (const T*)image.data;
int height = image.size().height;
int width = image.size().width;
int step = image.step1();
printf("print_cvmat()::Image of size height = %d, width = %d, step = %d\n", \
height, width, step );
for ( int row_i = 0; row_i < height; ++row_i )
{
int row_i_offset = row_i * step;
for ( int col_i = 0; col_i < width; ++col_i )
{
printf("%3.d ", img_ptr[ row_i_offset + col_i ]);
//printf("%3.d ", int( image.at<T>( row_i, col_i ) ) );
}
printf("\n");
}
}
/**
* @brief Extract RGB channel seprately from bayer image
*
* @tparam T data tyoe of bayer image.
* @return vector of RGB image. OpenCV internally maintain reference count.
* Thus this step won't create deep copy overhead.
*
* @example extract_rgb_fmom_bayer<uint16_t>( bayer_img, rgb_vector_container );
*/
template <typename T>
void extract_rgb_fmom_bayer( const cv::Mat& bayer_img, \
cv::Mat& red_img, cv::Mat& green_img1, cv::Mat& green_img2, cv::Mat& blue_img )
{
const T* bayer_img_ptr = (const T*)bayer_img.data;
int bayer_width = bayer_img.size().width;
int bayer_height = bayer_img.size().height;
int bayer_step = bayer_img.step1();
if ( bayer_width % 2 != 0 || bayer_height % 2 != 0 )
{
throw std::runtime_error("Bayer image data size incorrect, must be multiplier of 2\n");
}
// RGB image is half the size of bayer image
int rgb_width = bayer_width / 2;
int rgb_height = bayer_height / 2;
red_img.create( rgb_height, rgb_width, bayer_img.type() );
green_img1.create( rgb_height, rgb_width, bayer_img.type() );
green_img2.create( rgb_height, rgb_width, bayer_img.type() );
blue_img.create( rgb_height, rgb_width, bayer_img.type() );
int rgb_step = red_img.step1();
T* r_img_ptr = (T*)red_img.data;
T* g1_img_ptr = (T*)green_img1.data;
T* g2_img_ptr = (T*)green_img2.data;
T* b_img_ptr = (T*)blue_img.data;
for ( int rgb_row_i = 0; rgb_row_i < rgb_height; rgb_row_i++ )
{
int rgb_row_i_offset = rgb_row_i * rgb_step;
// Every RGB row corresbonding to two Bayer image row
int bayer_row_i_offset1 = ( rgb_row_i * 2 + 0 ) * bayer_step; // For RG
int bayer_row_i_offset2 = ( rgb_row_i * 2 + 1 ) * bayer_step; // For GB
for ( int rgb_col_j = 0; rgb_col_j < rgb_width; rgb_col_j++ )
{
r_img_ptr[ rgb_row_i_offset + rgb_col_j ] = bayer_img_ptr[ bayer_row_i_offset1 + ( rgb_col_j * 2 + 0 ) ];
g1_img_ptr[ rgb_row_i_offset + rgb_col_j ] = bayer_img_ptr[ bayer_row_i_offset1 + ( rgb_col_j * 2 + 1 ) ];
g2_img_ptr[ rgb_row_i_offset + rgb_col_j ] = bayer_img_ptr[ bayer_row_i_offset2 + ( rgb_col_j * 2 + 0 ) ];
b_img_ptr[ rgb_row_i_offset + rgb_col_j ] = bayer_img_ptr[ bayer_row_i_offset2 + ( rgb_col_j * 2 + 1 ) ];
}
}
}
} // namespace hdrplus } // namespace hdrplus

@ -1,31 +1,16 @@
#include <cstdio> #include <cstdio>
#include <vector> #include <vector>
#include <cstdint>
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
#include "hdrplus/utility.h" #include "hdrplus/utility.h"
template< typename T >
void print_cvmat( cv::Mat image )
{
int height = image.size().height;
int width = image.size().width;
for ( int row_i = 0; row_i < height; ++row_i )
{
for ( int col_i = 0; col_i < width; ++col_i )
{
printf("%2.d ", int( image.at<T>( row_i, col_i ) ) );
}
printf("\n");
}
}
void test_box_filter_2x2() void test_box_filter_2x2()
{ {
printf("\n###Test test_box_filter_2x2()###\n"); printf("\n###Test test_box_filter_2x2()###\n");
// Intialize input data // Intialize input data
int src_width = 10; int src_width = 10;
int src_height = 6; int src_height = 6;
std::vector<uint16_t> src_data( src_width, src_height ); std::vector<uint16_t> src_data( src_width * src_height );
for ( int i = 0; i < src_width * src_height; ++i ) for ( int i = 0; i < src_width * src_height; ++i )
{ {
@ -36,12 +21,14 @@ void test_box_filter_2x2()
cv::Mat src_image( src_height, src_width, CV_16U, src_data.data() ); cv::Mat src_image( src_height, src_width, CV_16U, src_data.data() );
printf("src cv::Mat is \n"); printf("src cv::Mat is \n");
print_cvmat<uint16_t>( src_image ); hdrplus::print_cvmat<uint16_t>( src_image );
cv::Mat dst_image = hdrplus::box_filter_2x2<uint16_t>( src_image ); cv::Mat dst_image = hdrplus::box_filter_2x2<uint16_t>( src_image );
printf("dst cv::Mat is \n"); printf("dst cv::Mat is \n");
print_cvmat<uint16_t>( dst_image ); hdrplus::print_cvmat<uint16_t>( dst_image );
printf("test_box_filter_2x2 finish\n"); fflush(stdout);
} }
void test_box_filter_kxk() void test_box_filter_kxk()
@ -50,7 +37,7 @@ void test_box_filter_kxk()
// Intialize input data // Intialize input data
int src_width = 12; int src_width = 12;
int src_height = 8; int src_height = 8;
std::vector<uint16_t> src_data( src_width, src_height ); std::vector<uint16_t> src_data( src_width * src_height );
for ( int i = 0; i < src_width * src_height; ++i ) for ( int i = 0; i < src_width * src_height; ++i )
{ {
@ -61,17 +48,57 @@ void test_box_filter_kxk()
cv::Mat src_image( src_height, src_width, CV_16U, src_data.data() ); cv::Mat src_image( src_height, src_width, CV_16U, src_data.data() );
printf("src cv::Mat is \n"); printf("src cv::Mat is \n");
print_cvmat<uint16_t>( src_image ); hdrplus::print_cvmat<uint16_t>( src_image );
cv::Mat dst_image = hdrplus::box_filter_kxk<uint16_t, 2>( src_image ); cv::Mat dst_image = hdrplus::box_filter_kxk<uint16_t, 2>( src_image );
printf("dst cv::Mat 2x2 is \n"); printf("dst cv::Mat 2x2 is \n");
print_cvmat<uint16_t>( dst_image ); hdrplus::print_cvmat<uint16_t>( dst_image );
dst_image = hdrplus::box_filter_kxk<uint16_t, 4>( src_image ); dst_image = hdrplus::box_filter_kxk<uint16_t, 4>( src_image );
printf("dst cv::Mat 4x4 is \n"); printf("dst cv::Mat 4x4 is \n");
print_cvmat<uint16_t>( dst_image ); hdrplus::print_cvmat<uint16_t>( dst_image );
printf("test_box_filter_kxk finish\n"); fflush(stdout);
}
void test_extract_rgb_from_bayer()
{
printf("\n###Test test_extract_rgb_from_bayer()###\n");
// Intialize input data
int bayer_width = 24;
int bayer_height = 16;
std::vector<uint16_t> bayer_data( bayer_width * bayer_height );
for ( int i = 0; i < bayer_width * bayer_height; ++i )
{
bayer_data[ i ] = i+1;
}
// Create input cv::mat
cv::Mat bayer_img = cv::Mat( bayer_height, bayer_width, CV_16U, bayer_data.data() );
cv::Mat red_img, green_img1, green_img2, blue_img;
printf("\nbayer cv::Mat is \n");
hdrplus::print_cvmat<uint16_t>( bayer_img );
hdrplus::extract_rgb_fmom_bayer<uint16_t>( bayer_img, red_img, green_img1, green_img2, blue_img );
printf("\nRed cv::Mat is \n");
hdrplus::print_cvmat<uint16_t>( red_img );
printf("\nGreen 1 cv::Mat is \n");
hdrplus::print_cvmat<uint16_t>( green_img1 );
printf("\nGreen 2 cv::Mat is \n");
hdrplus::print_cvmat<uint16_t>( green_img2 );
printf("\nBlue cv::Mat is \n");
hdrplus::print_cvmat<uint16_t>( blue_img );
printf("test_extract_rgb_from_bayer finish\n"); fflush(stdout);
} }
@ -79,4 +106,7 @@ int main()
{ {
test_box_filter_2x2(); test_box_filter_2x2();
test_box_filter_kxk(); test_box_filter_kxk();
test_extract_rgb_from_bayer();
printf("\ntest_utility finish\n");
} }
Loading…
Cancel
Save