diff options
-rw-r--r-- | modules/ocl/cl_fisheye_handler.cpp | 2 | ||||
-rw-r--r-- | modules/ocl/cl_image_handler.cpp | 2 | ||||
-rw-r--r-- | modules/ocl/cl_kernel.cpp | 1 | ||||
-rw-r--r-- | modules/ocl/cl_pyramid_blender.cpp | 29 | ||||
-rw-r--r-- | modules/ocl/cl_utils.cpp | 6 | ||||
-rw-r--r-- | modules/ocl/cl_video_stabilizer.cpp | 1 | ||||
-rw-r--r-- | modules/ocl/cv_edgetaper.cpp | 112 | ||||
-rw-r--r-- | modules/ocl/cv_edgetaper.h | 7 | ||||
-rw-r--r-- | modules/ocl/cv_feature_match.cpp | 5 | ||||
-rw-r--r-- | modules/ocl/cv_image_deblurring.cpp | 53 | ||||
-rw-r--r-- | modules/ocl/cv_image_deblurring.h | 6 | ||||
-rw-r--r-- | modules/ocl/cv_image_process_helper.cpp | 36 | ||||
-rw-r--r-- | modules/ocl/cv_image_process_helper.h | 4 | ||||
-rw-r--r-- | modules/ocl/cv_image_sharp.cpp | 16 | ||||
-rw-r--r-- | modules/ocl/cv_wiener_filter.cpp | 24 | ||||
-rw-r--r-- | modules/soft/cv_capi_feature_match.cpp | 5 | ||||
-rw-r--r-- | modules/soft/soft_geo_mapper.cpp | 1 | ||||
-rw-r--r-- | modules/soft/soft_stitcher.cpp | 1 | ||||
-rw-r--r-- | tests/test-image-deblurring.cpp | 92 | ||||
-rw-r--r-- | tests/test-image-stitching.cpp | 13 | ||||
-rw-r--r-- | tests/test-soft-image.cpp | 86 | ||||
-rw-r--r-- | xcore/image_processor.cpp | 2 |
22 files changed, 278 insertions, 226 deletions
diff --git a/modules/ocl/cl_fisheye_handler.cpp b/modules/ocl/cl_fisheye_handler.cpp index 93b62a5..a7866c5 100644 --- a/modules/ocl/cl_fisheye_handler.cpp +++ b/modules/ocl/cl_fisheye_handler.cpp @@ -393,7 +393,7 @@ CLFisheyeHandler::generate_fisheye_table ( size_t row_pitch; size_t slice_pitch; XCamReturn ret = _geo_table->enqueue_map ((void *&)map_ptr, origin, region, &row_pitch, &slice_pitch, CL_MAP_WRITE); - XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); + XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "CLFisheyeHandler mesh table failed in enqueue_map"); for (uint32_t row = 0; row < table_height; row++) { for(uint32_t col = 0; col < table_width; col++) { diff --git a/modules/ocl/cl_image_handler.cpp b/modules/ocl/cl_image_handler.cpp index c359bcd..f9fc56c 100644 --- a/modules/ocl/cl_image_handler.cpp +++ b/modules/ocl/cl_image_handler.cpp @@ -230,6 +230,8 @@ XCamReturn CLImageHandler::prepare_buffer_pool_video_info ( XCamReturn CLImageHandler::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output) { + XCAM_UNUSED (input); + XCAM_UNUSED (output); XCAM_ASSERT (input.ptr () && output.ptr ()); return XCAM_RETURN_NO_ERROR; } diff --git a/modules/ocl/cl_kernel.cpp b/modules/ocl/cl_kernel.cpp index 62dfcb7..fdda8ec 100644 --- a/modules/ocl/cl_kernel.cpp +++ b/modules/ocl/cl_kernel.cpp @@ -433,6 +433,7 @@ CLKernel::event_notify (cl_event event, cl_int status, void* data) KernelUserData *kernel_data = (KernelUserData *)data; XCAM_ASSERT (event == kernel_data->event->get_event_id ()); XCAM_UNUSED (status); + XCAM_UNUSED (event); delete kernel_data; } diff --git a/modules/ocl/cl_pyramid_blender.cpp b/modules/ocl/cl_pyramid_blender.cpp index c0f4dce..d42fdcf 100644 --- a/modules/ocl/cl_pyramid_blender.cpp +++ b/modules/ocl/cl_pyramid_blender.cpp @@ -353,7 +353,7 @@ PyramidLayer::bind_buf_to_layer0 ( cl_desc.width = XCAM_ALIGN_UP (this->blend_width, XCAM_CL_BLENDER_ALIGNMENT_X) / 8; cl_desc.height = XCAM_ALIGN_UP (this->blend_height, divider_vert[i_plane]) / divider_vert[i_plane]; uint32_t row_pitch = CLImage::calculate_pixel_bytes (cl_desc.format) * - XCAM_ALIGN_UP (cl_desc.width, XCAM_CL_IMAGE_ALIGNMENT_X); + XCAM_ALIGN_UP (cl_desc.width, XCAM_CL_IMAGE_ALIGNMENT_X); uint32_t size = row_pitch * cl_desc.height; SmartPtr<CLBuffer> cl_buf = new CLBuffer (context, size); XCAM_ASSERT (cl_buf.ptr () && cl_buf->is_valid ()); @@ -379,7 +379,11 @@ PyramidLayer::init_layer0 (SmartPtr<CLContext> context, bool last_layer, bool ne this->blend_mask[0] = new CLBuffer(context, mask_size); float *blend_ptr = NULL; XCamReturn ret = this->blend_mask[0]->enqueue_map((void*&)blend_ptr, 0, mask_size); - XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); + if (!xcam_ret_is_ok (ret)) { + XCAM_LOG_ERROR ("PyramidLayer init layer0 failed in blend_mask mem_map"); + return; + } + for (uint32_t i_ptr = 0; i_ptr < this->mask_width[0]; ++i_ptr) { if (i_ptr <= this->mask_width[0] / 2) blend_ptr[i_ptr] = 1.0f; @@ -438,7 +442,7 @@ PyramidLayer::build_cl_images (SmartPtr<CLContext> context, bool last_layer, boo //gauss y image created by cl buffer row_pitch = CLImage::calculate_pixel_bytes (cl_desc_set.format) * - XCAM_ALIGN_UP (cl_desc_set.width, XCAM_CL_IMAGE_ALIGNMENT_X); + XCAM_ALIGN_UP (cl_desc_set.width, XCAM_CL_IMAGE_ALIGNMENT_X); size = row_pitch * cl_desc_set.height; cl_buf = new CLBuffer (context, size); XCAM_ASSERT (cl_buf.ptr () && cl_buf->is_valid ()); @@ -451,7 +455,7 @@ PyramidLayer::build_cl_images (SmartPtr<CLContext> context, bool last_layer, boo cl_desc_set.width = XCAM_ALIGN_UP (this->blend_width, XCAM_CL_BLENDER_ALIGNMENT_X) / 8; cl_desc_set.height = XCAM_ALIGN_UP (this->blend_height, divider_vert[plane]) / divider_vert[plane]; row_pitch = CLImage::calculate_pixel_bytes (cl_desc_set.format) * - XCAM_ALIGN_UP (cl_desc_set.width, XCAM_CL_IMAGE_ALIGNMENT_X); + XCAM_ALIGN_UP (cl_desc_set.width, XCAM_CL_IMAGE_ALIGNMENT_X); size = row_pitch * cl_desc_set.height; cl_buf = new CLBuffer (context, size); XCAM_ASSERT (cl_buf.ptr () && cl_buf->is_valid ()); @@ -491,9 +495,9 @@ PyramidLayer::copy_mask_from_y_to_uv (SmartPtr<CLContext> &context) float *from_ptr = NULL; float *to_ptr = NULL; ret = this->blend_mask[1]->enqueue_map ((void*&)to_ptr, 0, this->mask_width[1] * sizeof(float)); - XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); + XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), false, "PyramidLayer copy mask failed in blend_mask[1] mem_map"); ret = this->blend_mask[0]->enqueue_map((void*&)from_ptr, 0, this->mask_width[0] * sizeof(float)); - XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); + XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), false, "PyramidLayer copy mask failed in blend_mask[0] mem_map"); for (int i = 0; i < (int)this->mask_width[1]; ++i) { if (i * 2 + 1 >= (int)this->mask_width[0]) { // todo i* 2 + 1 @@ -532,7 +536,10 @@ CLPyramidBlender::dump_layer_mask (uint32_t layer, bool is_uv) float *mask_ptr = NULL; XCamReturn ret = pyr_layer.blend_mask[plane]->enqueue_map ((void*&)mask_ptr, 0, pyr_layer.mask_width[plane] * sizeof(float)); - XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); + if (!xcam_ret_is_ok (ret)) { + XCAM_LOG_ERROR ("CLPyramidBlender dump mask failed in blend_mask(layer:%d) mem_map", layer); + return; + } printf ("layer(%d)(-%s) mask, width:%d\n", layer, (is_uv ? "UV" : "Y"), pyr_layer.mask_width[plane]); for (uint32_t i = 0; i < pyr_layer.mask_width[plane]; ++i) { @@ -560,10 +567,10 @@ gauss_fill_mask ( XCAM_ASSERT (to.blend_mask[0].ptr ()); float *mask0_ptr = NULL; ret = to.blend_mask[0]->enqueue_map((void*&)mask0_ptr, 0, mask_size); - XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); + XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), false, "gauss_fill_mask failed in destination image mem_map"); ret = prev.blend_mask[0]->enqueue_map((void*&)pre_ptr, 0, prev_size); - XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); + XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), false, "gauss_fill_mask failed in source image mem_map"); for (i = 0; i < (int)to.blend_width; ++i) { if (i * 2 + 1 >= (int)prev.mask_width[0]) { // todo i* 2 + 1 @@ -659,7 +666,7 @@ CLPyramidBlender::init_seam_buffers (SmartPtr<CLContext> context) cl_desc.width = _seam_width / 8; cl_desc.height = _seam_height; cl_desc.row_pitch = CLImage::calculate_pixel_bytes (cl_desc.format) * - XCAM_ALIGN_UP (cl_desc.width, XCAM_CL_IMAGE_ALIGNMENT_X); + XCAM_ALIGN_UP (cl_desc.width, XCAM_CL_IMAGE_ALIGNMENT_X); uint32_t image_diff_size = cl_desc.row_pitch * _seam_height; SmartPtr<CLBuffer> cl_diff_buf = new CLBuffer (context, image_diff_size); @@ -695,7 +702,7 @@ CLPyramidBlender::init_seam_buffers (SmartPtr<CLContext> context) cl_desc.width = mask_width / 8; cl_desc.height = mask_height; cl_desc.row_pitch = CLImage::calculate_pixel_bytes (cl_desc.format) * - XCAM_ALIGN_UP (cl_desc.width, XCAM_CL_IMAGE_ALIGNMENT_X); + XCAM_ALIGN_UP (cl_desc.width, XCAM_CL_IMAGE_ALIGNMENT_X); uint32_t mask_size = cl_desc.row_pitch * mask_height; SmartPtr<CLBuffer> cl_buf0 = new CLBuffer (context, mask_size); diff --git a/modules/ocl/cl_utils.cpp b/modules/ocl/cl_utils.cpp index 55b59f5..b8ce3a9 100644 --- a/modules/ocl/cl_utils.cpp +++ b/modules/ocl/cl_utils.cpp @@ -60,7 +60,7 @@ dump_image (SmartPtr<CLImage> image, const char *file_name) size_t slice_pitch; XCamReturn ret = image->enqueue_map (ptr, origin, region, &row_pitch, &slice_pitch, CL_MAP_READ); - XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); + XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), false, "dump image failed in enqueue_map"); XCAM_ASSERT (ptr); XCAM_ASSERT (row_pitch == desc.row_pitch); uint8_t *buf_start = (uint8_t *)ptr; @@ -156,7 +156,9 @@ convert_nv12_mem_to_video_buffer ( VideoBufferPlanarInfo planar; const VideoBufferInfo info = buf->get_video_info (); - XCAM_ASSERT ((width == info.width) && (height == info.height)); + XCAM_FAIL_RETURN ( + DEBUG, (width == info.width) && (height == info.height), XCAM_RETURN_ERROR_PARAM, + "convert mem to video buffer failed since image sizes are not matched."); uint8_t *out_mem = buf->map (); XCAM_FAIL_RETURN (ERROR, out_mem, XCAM_RETURN_ERROR_MEM, "map buffer failed"); diff --git a/modules/ocl/cl_video_stabilizer.cpp b/modules/ocl/cl_video_stabilizer.cpp index 66deadf..73b92fe 100644 --- a/modules/ocl/cl_video_stabilizer.cpp +++ b/modules/ocl/cl_video_stabilizer.cpp @@ -109,6 +109,7 @@ CLVideoStabilizer::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<Vi { XCamReturn ret = XCAM_RETURN_NO_ERROR; XCAM_ASSERT (input.ptr () && output.ptr ()); + XCAM_UNUSED (output); if (_input_buf_list.size () >= 2 * _filter_radius + 1) { _input_buf_list.pop_front (); diff --git a/modules/ocl/cv_edgetaper.cpp b/modules/ocl/cv_edgetaper.cpp index a07eeac..ab79238 100644 --- a/modules/ocl/cv_edgetaper.cpp +++ b/modules/ocl/cv_edgetaper.cpp @@ -25,86 +25,60 @@ namespace XCam { CVEdgetaper::CVEdgetaper () - : CVBaseClass() + : CVBaseClass () { } void -CVEdgetaper::normalized_autocorrelation (const cv::Mat &psf, cv::Mat &auto_correlation_psf) +CVEdgetaper::create_weights (const cv::Mat &image, const cv::Mat &psf, cv::Mat &coefficients) { - cv::Mat correlation; - cv::copyMakeBorder (psf, auto_correlation_psf, psf.cols - 1, 0, psf.rows - 1, 0, cv::BORDER_CONSTANT, cv::Scalar::all(0)); - cv::filter2D (auto_correlation_psf, correlation, -1, psf, cv::Point(0, 0), 0, cv::BORDER_CONSTANT); - cv::normalize (correlation, correlation, 0, 1.0f, cv::NORM_MINMAX); - auto_correlation_psf = correlation.clone (); + cv::Mat rows_proj, cols_proj; + cv::Mat rows_proj_border, cols_proj_border; + cv::Mat rows_cor, cols_cor; + // get psf rows and cols projections + cv::reduce (psf, rows_proj, 1, CV_REDUCE_SUM, -1); + cv::reduce (psf, cols_proj, 0, CV_REDUCE_SUM, -1); + // calculate correlation for psf projections + cv::copyMakeBorder (rows_proj, rows_proj_border, (psf.rows - 1) / 2, (psf.rows - 1) / 2, 0, 0, cv::BORDER_CONSTANT, cv::Scalar::all (0)); + cv::copyMakeBorder (cols_proj, cols_proj_border, 0, 0, (psf.cols - 1) / 2, (psf.cols - 1) / 2, cv::BORDER_CONSTANT, cv::Scalar::all (0)); + cv::matchTemplate (rows_proj_border, rows_proj, rows_cor, CV_TM_CCORR); + cv::matchTemplate (cols_proj_border, cols_proj, cols_cor, CV_TM_CCORR); + // make it symmetric on both sides + cv::Mat rows_add = cv::Mat_<float>(1, 1) << rows_proj.at<float> (0, 0); + cv::Mat cols_add = cv::Mat_<float>(1, 1) << cols_proj.at<float> (0, 0); + cv::vconcat (rows_cor, rows_add, rows_cor); + cv::hconcat (cols_cor, cols_add, cols_cor); + double min, max; + cv::minMaxLoc (rows_cor, &min, &max); + rows_cor /= max; + cv::minMaxLoc (cols_cor, &min, &max); + cols_cor /= max; + // get matrix from projections + cv::Mat alpha = (cv::Scalar (1) - rows_proj) * (cv::Scalar (1) - cols_proj); + // expand it to the image size + int nc = image.cols / psf.cols + 1; + int nr = image.rows / psf.rows + 1; + cv::Mat expanded; + cv::repeat (alpha, nr, nc, expanded); + cv::Mat weights = expanded (cv::Rect (expanded.cols / 2 - image.cols / 2, expanded.rows / 2 - image.rows / 2, image.cols, image.rows)); + coefficients = weights.clone (); } void -CVEdgetaper::create_weights (cv::Mat &coefficients, const cv::Mat &psf) -{ - int psfr_last = psf.rows - 1; - int psfc_last = psf.cols - 1; - - cv::Mat auto_correlation_psf; - normalized_autocorrelation(psf, auto_correlation_psf); - - for (int i = 0; i < coefficients.rows; i++) - { - for (int j = 0; j < coefficients.cols; j++) { - if (i < psfr_last) - { - if (j < psfc_last) - coefficients.at<float>(i, j) = auto_correlation_psf.at<float>(i, j); - else if (psfc_last <= j && j < (coefficients.cols - psfc_last)) - coefficients.at<float>(i, j) = auto_correlation_psf.at<float>(i, psfc_last); - else - coefficients.at<float>(i, j) = auto_correlation_psf.at<float>(i, j - (coefficients.cols - 2 * psfc_last) + 1); - } - else if (psfr_last <= i && i < (coefficients.rows - psfr_last)) - { - if (j < psfc_last) - coefficients.at<float>(i, j) = auto_correlation_psf.at<float>(psfr_last, j); - else if (psfc_last <= j && j < (coefficients.cols - psfc_last)) - coefficients.at<float>(i, j) = 1.0f; - else - coefficients.at<float>(i, j) = auto_correlation_psf.at<float>(psfr_last, j - (coefficients.cols - 2 * psfc_last) + 1); - } - else - { - if (j < psfc_last) - coefficients.at<float>(i, j) = auto_correlation_psf.at<float>(i - (coefficients.rows - 2 * psfr_last) + 1, j); - else if (psfc_last <= j && j < (coefficients.cols - psfc_last)) - coefficients.at<float>(i, j) = auto_correlation_psf.at<float>(i - (coefficients.rows - 2 * psfr_last) + 1, psfc_last); - else - coefficients.at<float>(i, j) = auto_correlation_psf.at<float>(i - (coefficients.rows - 2 * psfr_last) + 1, j - (coefficients.cols - 2 * psfc_last) + 1); - } - } - } -} - -cv::Mat -CVEdgetaper::edgetaper (const cv::Mat &img, const cv::Mat &psf) +CVEdgetaper::edgetaper (const cv::Mat &img, const cv::Mat &psf, cv::Mat &output) { cv::Mat blurred = cv::Mat::zeros (img.rows, img.cols, CV_32FC1); - cv::filter2D (img, blurred, CV_32F, psf, cv::Point(-1, -1), 0, cv::BORDER_CONSTANT); - - cv::Mat coefficients = cv::Mat::zeros (img.rows, img.cols, CV_32FC1); - create_weights (coefficients, psf); - cv::Mat result = img.clone (); - result.convertTo (result, CV_32FC1); - for (int i = 0; i < img.rows; i++) - { - for (int j = 0; j < img.cols; j++) - { - if (coefficients.at<float>(i, j) != 1.0f) - { - result.at<float>(i, j) = img.at<unsigned char>(i, j) * coefficients.at<float>(i, j) + - blurred.at<float>(i, j) * (1.0f - coefficients.at<float>(i, j)); - } - } - } - return result; + // flip PSF to perform convolution + cv::Mat psf_flipped; + cv::flip (psf, psf_flipped, -1); + cv::filter2D (img, blurred, CV_32FC1, psf_flipped, cv::Point (-1, -1), 0, cv::BORDER_CONSTANT); + cv::Mat coefficients; + create_weights (img, psf, coefficients); + cv::Mat result; + img.convertTo (result, CV_32FC1); + result = result.mul (coefficients) + blurred.mul (cv::Scalar (1.0f) - coefficients); + output = result.clone (); } } diff --git a/modules/ocl/cv_edgetaper.h b/modules/ocl/cv_edgetaper.h index 9c00fc7..1ead29f 100644 --- a/modules/ocl/cv_edgetaper.h +++ b/modules/ocl/cv_edgetaper.h @@ -30,17 +30,16 @@ namespace XCam { + class CVEdgetaper : public CVBaseClass { public: explicit CVEdgetaper (); - - cv::Mat edgetaper (const cv::Mat &image, const cv::Mat &psf); + void edgetaper (const cv::Mat &image, const cv::Mat &psf, cv::Mat &output); private: - void create_weights (cv::Mat &coefficients, const cv::Mat &psf); - void normalized_autocorrelation (const cv::Mat &psf, cv::Mat &auto_correlation_psf); + void create_weights (const cv::Mat &image, const cv::Mat &psf, cv::Mat &coefficients); XCAM_DEAD_COPY (CVEdgetaper); }; diff --git a/modules/ocl/cv_feature_match.cpp b/modules/ocl/cv_feature_match.cpp index d670446..e4e2ea8 100644 --- a/modules/ocl/cv_feature_match.cpp +++ b/modules/ocl/cv_feature_match.cpp @@ -121,12 +121,13 @@ CVFeatureMatch::calc_of_match ( { cv::_InputOutputArray debug_img; cv::Size img0_size = image0.size (); - cv::Size img1_size = image1.size (); - XCAM_ASSERT (img0_size.height == img1_size.height); + XCAM_ASSERT (img0_size.height == image1.rows ()); + XCAM_UNUSED (image1); #if XCAM_CV_FM_DEBUG cv::Mat mat; cv::UMat umat; + cv::Size img1_size = image1.size (); cv::Size size (img0_size.width + img1_size.width, img0_size.height); if (image0.isUMat ()) { diff --git a/modules/ocl/cv_image_deblurring.cpp b/modules/ocl/cv_image_deblurring.cpp index c036b42..730eb42 100644 --- a/modules/ocl/cv_image_deblurring.cpp +++ b/modules/ocl/cv_image_deblurring.cpp @@ -25,12 +25,12 @@ namespace XCam { CVImageDeblurring::CVImageDeblurring () - : CVBaseClass() + : CVBaseClass () { - _helper = new CVImageProcessHelper(); - _sharp = new CVImageSharp(); - _edgetaper = new CVEdgetaper(); - _wiener = new CVWienerFilter(); + _helper = new CVImageProcessHelper (); + _sharp = new CVImageSharp (); + _edgetaper = new CVEdgetaper (); + _wiener = new CVWienerFilter (); } void @@ -152,35 +152,52 @@ CVImageDeblurring::estimate_kernel_size (const cv::Mat &image) } void -CVImageDeblurring::blind_deblurring (const cv::Mat &blurred, cv::Mat &deblurred, cv::Mat &kernel, int kernel_size, float noise_power) +CVImageDeblurring::blind_deblurring (const cv::Mat &blurred, cv::Mat &deblurred, cv::Mat &kernel, int kernel_size, float noise_power, bool use_edgetaper) { cv::Mat gray_blurred; cv::cvtColor (blurred, gray_blurred, CV_BGR2GRAY); - if (noise_power < 0) { + if (noise_power < 0) + { cv::Mat median_blurred; medianBlur (gray_blurred, median_blurred, 3); noise_power = 1.0f / _helper->get_snr (gray_blurred, median_blurred); - XCAM_LOG_DEBUG("estimated inv snr %f", noise_power); + XCAM_LOG_DEBUG ("estimated inv snr %f", noise_power); } - if (kernel_size < 0) { + if (kernel_size < 0) + { kernel_size = estimate_kernel_size (gray_blurred); - XCAM_LOG_DEBUG("estimated kernel size %d", kernel_size); + XCAM_LOG_DEBUG ("estimated kernel size %d", kernel_size); + } + if (use_edgetaper) { + XCAM_LOG_DEBUG ("edgetaper will be used"); + } + else { + XCAM_LOG_DEBUG ("edgetaper will not be used"); } - std::vector<cv::Mat> blurred_rgb(3); - cv::split(blurred, blurred_rgb); - std::vector<cv::Mat> deblurred_rgb(3); + std::vector<cv::Mat> blurred_rgb (3); + cv::split (blurred, blurred_rgb); + std::vector<cv::Mat> deblurred_rgb (3); cv::Mat result_deblurred; cv::Mat result_kernel; blind_deblurring_one_channel (gray_blurred, result_kernel, kernel_size, noise_power); for (int i = 0; i < 3; i++) { - _wiener->wiener_filter (_edgetaper->edgetaper(blurred_rgb[i], result_kernel), result_kernel, deblurred_rgb[i], noise_power); + cv::Mat input; + if (use_edgetaper) + { + _edgetaper->edgetaper (blurred_rgb[i], result_kernel, input); + } + else + { + input = blurred_rgb[i].clone (); + } + _wiener->wiener_filter (input, result_kernel, deblurred_rgb[i], noise_power); _helper->apply_constraints (deblurred_rgb[i], 0); } cv::merge (deblurred_rgb, result_deblurred); result_deblurred.convertTo (result_deblurred, CV_8UC3); fastNlMeansDenoisingColored (result_deblurred, deblurred, 3, 3, 7, 21); - kernel = result_kernel.clone(); + kernel = result_kernel.clone (); } void @@ -189,19 +206,17 @@ CVImageDeblurring::blind_deblurring_one_channel (const cv::Mat &blurred, cv::Mat cv::Mat kernel_current = cv::Mat::zeros (kernel_size, kernel_size, CV_32FC1); cv::Mat deblurred_current = _helper->erosion (blurred, 2, 0); float sigmar = 20; - cv::Mat enhanced_blurred = blurred.clone (); for (int i = 0; i < _config.iterations; i++) { cv::Mat sharpened = _sharp->sharp_image_gray (deblurred_current, sigmar); _wiener->wiener_filter (blurred, sharpened.clone (), kernel_current, noise_power); - kernel_current = kernel_current (cv::Rect(0, 0, kernel_size, kernel_size)); + kernel_current = kernel_current (cv::Rect (0, 0, kernel_size, kernel_size)); double min_val; double max_val; cv::minMaxLoc (kernel_current, &min_val, &max_val); _helper->apply_constraints (kernel_current, (float)max_val / 20); _helper->normalize_weights (kernel_current); - enhanced_blurred = _edgetaper->edgetaper (blurred, kernel_current); - _wiener->wiener_filter (enhanced_blurred, kernel_current.clone(), deblurred_current, noise_power); + _wiener->wiener_filter (blurred, kernel_current.clone(), deblurred_current, noise_power); _helper->apply_constraints (deblurred_current, 0); sigmar *= 0.9; } diff --git a/modules/ocl/cv_image_deblurring.h b/modules/ocl/cv_image_deblurring.h index f46de35..afac22c 100644 --- a/modules/ocl/cv_image_deblurring.h +++ b/modules/ocl/cv_image_deblurring.h @@ -35,7 +35,7 @@ namespace XCam { struct CVIDConfig { int iterations; // number of iterations for IBD algorithm - CVIDConfig (unsigned int _iterations = 200) + CVIDConfig (unsigned int _iterations = 50) { iterations = _iterations; } @@ -46,11 +46,9 @@ class CVImageDeblurring : public CVBaseClass public: explicit CVImageDeblurring (); - void set_config (CVIDConfig config); CVIDConfig get_config (); - - void blind_deblurring (const cv::Mat &blurred, cv::Mat &deblurred, cv::Mat &kernel, int kernel_size = -1, float noise_power = -1.0f); + void blind_deblurring (const cv::Mat &blurred, cv::Mat &deblurred, cv::Mat &kernel, int kernel_size = -1, float noise_power = -1.0f, bool use_edgetaper = true); private: void blind_deblurring_one_channel (const cv::Mat &blurred, cv::Mat &kernel, int kernel_size, float noise_power); diff --git a/modules/ocl/cv_image_process_helper.cpp b/modules/ocl/cv_image_process_helper.cpp index 9698acc..0d08289 100644 --- a/modules/ocl/cv_image_process_helper.cpp +++ b/modules/ocl/cv_image_process_helper.cpp @@ -25,7 +25,7 @@ namespace XCam { CVImageProcessHelper::CVImageProcessHelper () - : CVBaseClass() + : CVBaseClass () { } @@ -34,11 +34,11 @@ cv::Mat CVImageProcessHelper::erosion (const cv::Mat &image, int erosion_size, int erosion_type) { cv::Mat element = cv::getStructuringElement (erosion_type, - cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1 ), - cv::Point(erosion_size, erosion_size)); + cv::Size (2 * erosion_size + 1, 2 * erosion_size + 1), + cv::Point (erosion_size, erosion_size)); cv::Mat eroded; cv::erode (image, eroded, element); - return eroded.clone(); + return eroded.clone (); } float @@ -55,17 +55,6 @@ CVImageProcessHelper::get_snr (const cv::Mat &noisy, const cv::Mat &noiseless) return res; } -cv::Mat -CVImageProcessHelper::get_auto_correlation (const cv::Mat &image) -{ - cv::Mat dst; - cv::Laplacian (image, dst, -1, 3, 1, 0, cv::BORDER_CONSTANT); - dst.convertTo (dst, CV_32FC1); - cv::Mat correlation; - cv::filter2D (dst, correlation, -1, dst, cv::Point(-1, -1), 0, cv::BORDER_CONSTANT); - return correlation.clone (); -} - void CVImageProcessHelper::compute_dft (const cv::Mat &image, cv::Mat &result) { @@ -73,7 +62,7 @@ CVImageProcessHelper::compute_dft (const cv::Mat &image, cv::Mat &result) int m = cv::getOptimalDFTSize (image.rows); int n = cv::getOptimalDFTSize (image.cols); cv::copyMakeBorder (image, padded, 0, m - image.rows, 0, n - image.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0)); - cv::Mat planes[] = {cv::Mat_<float>(padded), cv::Mat::zeros(padded.size(), CV_32FC1)}; + cv::Mat planes[] = {cv::Mat_<float> (padded), cv::Mat::zeros (padded.size (), CV_32FC1)}; cv::merge (planes, 2, result); cv::dft (result, result); } @@ -103,24 +92,11 @@ CVImageProcessHelper::apply_constraints (cv::Mat &image, float threshold_min_val } } -// weights will be symmetric and sum(weights elements) == 1 void CVImageProcessHelper::normalize_weights (cv::Mat &weights) { weights.convertTo (weights, CV_32FC1); - float sum = 0; - for (int i = 0; i < weights.rows; i++) - { - for (int j = 0; j <= i; j++) - { - weights.at<float>(i, j) = (weights.at<float>(i, j) + weights.at<float>(j, i)) / 2; - weights.at<float>(j, i) = weights.at<float>(i, j); - if (j == i) - sum += weights.at<float>(i, j); - else - sum += (2 * weights.at<float>(i, j)); - } - } + float sum = cv::sum (weights)[0]; weights /= sum; } diff --git a/modules/ocl/cv_image_process_helper.h b/modules/ocl/cv_image_process_helper.h index d1dbb72..137ff6b 100644 --- a/modules/ocl/cv_image_process_helper.h +++ b/modules/ocl/cv_image_process_helper.h @@ -37,12 +37,10 @@ public: void compute_dft (const cv::Mat &image, cv::Mat &result); void compute_idft (cv::Mat *input, cv::Mat &result); - void apply_constraints (cv::Mat &image, float threshold_min_value, float threshold_max_value = 255.0f, float min_value = 0.0f, float max_value = 255.0f); + void apply_constraints (cv::Mat &image, float threshold_min_value = 0.0f, float threshold_max_value = 255.0f, float min_value = 0.0f, float max_value = 255.0f); float get_snr (const cv::Mat &noisy, const cv::Mat &noiseless); cv::Mat erosion (const cv::Mat &image, int erosion_size, int erosion_type); - // weights will be symmetric and sum(weights elements) == 1 void normalize_weights (cv::Mat &weights); - cv::Mat get_auto_correlation (const cv::Mat &image); XCAM_DEAD_COPY (CVImageProcessHelper); }; diff --git a/modules/ocl/cv_image_sharp.cpp b/modules/ocl/cv_image_sharp.cpp index 7ca087b..0a309af 100644 --- a/modules/ocl/cv_image_sharp.cpp +++ b/modules/ocl/cv_image_sharp.cpp @@ -25,7 +25,7 @@ namespace XCam { CVImageSharp::CVImageSharp () - : CVBaseClass() + : CVBaseClass () { } @@ -36,34 +36,24 @@ CVImageSharp::sharp_image_gray (const cv::Mat &image, float sigmar) cv::Mat temp_image; image.convertTo (temp_image, CV_32FC1); cv::Mat bilateral_image; - cv::bilateralFilter (image, bilateral_image, 5, sigmar, 2); + cv::bilateralFilter (temp_image, bilateral_image, 5, sigmar, 2); cv::Mat sharp_filter = (cv::Mat_<float>(3, 3) << -1, -1, -1, -1, 8, -1, -1, -1, -1); cv::Mat filtered_image; cv::filter2D (bilateral_image, filtered_image, -1, sharp_filter); - filtered_image.convertTo (filtered_image, CV_32FC1); cv::normalize (filtered_image, filtered_image, 0, 255.0f, cv::NORM_MINMAX); - cv::Mat sharpened = temp_image + filtered_image; cv::normalize (sharpened, sharpened, 0, 255.0f, cv::NORM_MINMAX); return sharpened.clone (); } - float CVImageSharp::measure_sharp (const cv::Mat &image) { cv::Mat dst; cv::Laplacian (image, dst, -1, 3, 1, 0, cv::BORDER_CONSTANT); dst.convertTo (dst, CV_8UC1); - float sum = 0; - for (int i = 0; i < image.rows; i++) - { - for (int j = 0; j < image.cols; j++) - { - sum += dst.at<unsigned char>(i, j); - } - } + float sum = cv::sum (dst)[0]; sum /= (image.rows * image.cols); return sum; } diff --git a/modules/ocl/cv_wiener_filter.cpp b/modules/ocl/cv_wiener_filter.cpp index fb3401e..ff96e5c 100644 --- a/modules/ocl/cv_wiener_filter.cpp +++ b/modules/ocl/cv_wiener_filter.cpp @@ -25,20 +25,20 @@ namespace XCam { CVWienerFilter::CVWienerFilter () - : CVBaseClass() + : CVBaseClass () { - _helpers = new CVImageProcessHelper(); + _helpers = new CVImageProcessHelper (); } void CVWienerFilter::wiener_filter (const cv::Mat &blurred_image, const cv::Mat &known, cv::Mat &unknown, float noise_power) { - int image_w = blurred_image.size().width; - int image_h = blurred_image.size().height; + int image_w = blurred_image.size ().width; + int image_h = blurred_image.size ().height; cv::Mat y_ft; _helpers->compute_dft (blurred_image, y_ft); - cv::Mat padded = cv::Mat::zeros(image_h, image_w, CV_32FC1); + cv::Mat padded = cv::Mat::zeros (image_h, image_w, CV_32FC1); int padx = padded.cols - known.cols; int pady = padded.rows - known.rows; cv::copyMakeBorder (known, padded, 0, pady, 0, padx, cv::BORDER_CONSTANT, cv::Scalar::all(0)); @@ -47,22 +47,22 @@ CVWienerFilter::wiener_filter (const cv::Mat &blurred_image, const cv::Mat &know cv::Mat temp_unknown; cv::Mat unknown_ft[2]; - unknown_ft[0] = cv::Mat::zeros(image_h, image_w, CV_32FC1); - unknown_ft[1] = cv::Mat::zeros(image_h, image_w, CV_32FC1); + unknown_ft[0] = cv::Mat::zeros (image_h, image_w, CV_32FC1); + unknown_ft[1] = cv::Mat::zeros (image_h, image_w, CV_32FC1); cv::Mat denominator; - cv::Mat denominator_splitted[] = {cv::Mat::zeros(blurred_image.size(), CV_32FC1), cv::Mat::zeros(blurred_image.size(), CV_32FC1)}; + cv::Mat denominator_splitted[] = {cv::Mat::zeros (blurred_image.size (), CV_32FC1), cv::Mat::zeros (blurred_image.size (), CV_32FC1)}; cv::mulSpectrums (padded_ft, padded_ft, denominator, 0, true); cv::split (denominator, denominator_splitted); - denominator_splitted[0] = denominator_splitted[0](cv::Rect (0, 0, blurred_image.cols, blurred_image.rows)); + denominator_splitted[0] = denominator_splitted[0] (cv::Rect (0, 0, blurred_image.cols, blurred_image.rows)); denominator_splitted[0] += cv::Scalar (noise_power); cv::Mat numerator; - cv::Mat numerator_splitted[] = {cv::Mat::zeros(blurred_image.size(), CV_32FC1), cv::Mat::zeros(blurred_image.size(), CV_32FC1)}; + cv::Mat numerator_splitted[] = {cv::Mat::zeros (blurred_image.size (), CV_32FC1), cv::Mat::zeros (blurred_image.size (), CV_32FC1)}; cv::mulSpectrums (y_ft, padded_ft, numerator, 0, true); cv::split (numerator, numerator_splitted); - numerator_splitted[0] = numerator_splitted[0](cv::Rect (0, 0, blurred_image.cols, blurred_image.rows)); - numerator_splitted[1] = numerator_splitted[1](cv::Rect (0, 0, blurred_image.cols, blurred_image.rows)); + numerator_splitted[0] = numerator_splitted[0] (cv::Rect (0, 0, blurred_image.cols, blurred_image.rows)); + numerator_splitted[1] = numerator_splitted[1] (cv::Rect (0, 0, blurred_image.cols, blurred_image.rows)); cv::divide (numerator_splitted[0], denominator_splitted[0], unknown_ft[0]); cv::divide (numerator_splitted[1], denominator_splitted[0], unknown_ft[1]); _helpers->compute_idft (unknown_ft, temp_unknown); diff --git a/modules/soft/cv_capi_feature_match.cpp b/modules/soft/cv_capi_feature_match.cpp index c4a38ac..0e0081c 100644 --- a/modules/soft/cv_capi_feature_match.cpp +++ b/modules/soft/cv_capi_feature_match.cpp @@ -134,8 +134,8 @@ CVCapiFeatureMatch::calc_of_match ( { CvMat debug_image; CvSize img0_size = cvSize(((CvMat*)image0)->width, ((CvMat*)image0)->height); - CvSize img1_size = cvSize(((CvMat*)image1)->width, ((CvMat*)image1)->height); - XCAM_ASSERT (img0_size.height == img1_size.height); + XCAM_ASSERT (img0_size.height == ((CvMat*)image1)->height); + XCAM_UNUSED (image1); std::vector<float> offsets; float offset_sum = 0.0f; @@ -144,6 +144,7 @@ CVCapiFeatureMatch::calc_of_match ( offsets.reserve (corner0.size ()); #if XCAM_CV_CAPI_FM_DEBUG + CvSize img1_size = cvSize(((CvMat*)image1)->width, ((CvMat*)image1)->height); cv::Mat mat; mat.create (img0_size.height, img0_size.width + img1_size.width, ((CvMat*)image0)->type); debug_image = cvMat (img0_size.height, img0_size.width + img1_size.width, ((CvMat*)image0)->type, mat.ptr()); diff --git a/modules/soft/soft_geo_mapper.cpp b/modules/soft/soft_geo_mapper.cpp index 88ee870..478b025 100644 --- a/modules/soft/soft_geo_mapper.cpp +++ b/modules/soft/soft_geo_mapper.cpp @@ -178,6 +178,7 @@ void SoftGeoMapper::remap_task_done ( const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error) { + XCAM_UNUSED (worker); XCAM_ASSERT (worker.ptr () == _map_task.ptr ()); SmartPtr<XCamSoftTasks::GeoMapTask::Args> args = base.dynamic_cast_ptr<XCamSoftTasks::GeoMapTask::Args> (); XCAM_ASSERT (args.ptr ()); diff --git a/modules/soft/soft_stitcher.cpp b/modules/soft/soft_stitcher.cpp index 895597a..c345dcd 100644 --- a/modules/soft/soft_stitcher.cpp +++ b/modules/soft/soft_stitcher.cpp @@ -843,6 +843,7 @@ SoftStitcher::copy_task_done ( const SmartPtr<Worker::Arguments> &base, const XCamReturn error) { + XCAM_UNUSED (worker); XCAM_ASSERT (worker.ptr ()); SmartPtr<SoftSitcherPriv::StitcherCopyArgs> args = base.dynamic_cast_ptr<SoftSitcherPriv::StitcherCopyArgs> (); XCAM_ASSERT (args.ptr ()); diff --git a/tests/test-image-deblurring.cpp b/tests/test-image-deblurring.cpp index d71a448..bc681b2 100644 --- a/tests/test-image-deblurring.cpp +++ b/tests/test-image-deblurring.cpp @@ -21,46 +21,85 @@ #include "test_common.h" #include "test_inline.h" + #include <unistd.h> #include <getopt.h> #include <image_file_handle.h> -#include <ocl/cl_device.h> -#include <ocl/cl_context.h> -#include <ocl/cl_blender.h> +#include <ocl/cv_image_sharp.h> +#include <ocl/cv_wiener_filter.h> #include <ocl/cv_image_deblurring.h> + #include <opencv2/opencv.hpp> #include <opencv2/core/ocl.hpp> using namespace XCam; static void -usage(const char* arg0) +usage (const char* arg0) { printf ("Usage: %s --input file --output file\n" "\t--input, input image(RGB)\n" "\t--output, output image(RGB) PREFIX\n" + "\t--blind, optional, blind or non-blind deblurring, default true; select from [true/false]\n" "\t--save, optional, save file or not, default true; select from [true/false]\n" "\t--help, usage\n", arg0); } +static void +blind_deblurring (cv::Mat &input_image, cv::Mat &output_image) +{ + SmartPtr<CVImageDeblurring> image_deblurring = new CVImageDeblurring (); + cv::Mat kernel; + image_deblurring->blind_deblurring (input_image, output_image, kernel, -1, -1, false); +} + +static void +non_blind_deblurring (cv::Mat &input_image, cv::Mat &output_image) +{ + SmartPtr<CVWienerFilter> wiener_filter = new CVWienerFilter (); + cv::cvtColor (input_image, input_image, CV_BGR2GRAY); + // use simple motion blur kernel + int kernel_size = 13; + cv::Mat kernel = cv::Mat::zeros (kernel_size, kernel_size, CV_32FC1); + for (int i = 0; i < kernel_size; i++) + { + kernel.at<float> ((kernel_size - 1) / 2, i) = 1.0; + } + kernel /= kernel_size; + //flip kernel to perform convolution + cv::Mat conv_kernel; + cv::flip (kernel, conv_kernel, -1); + cv::Mat blurred; + cv::filter2D (input_image, blurred, CV_32FC1, conv_kernel, cv::Point(-1, -1), 0, cv::BORDER_CONSTANT); + // restore the image + cv::Mat median_blurred; + medianBlur (blurred, median_blurred, 3); + SmartPtr<CVImageProcessHelper> helpers = new CVImageProcessHelper (); + float noise_power = 1.0f / helpers->get_snr (blurred, median_blurred); + wiener_filter->wiener_filter (blurred, kernel, output_image, noise_power); +} + int main (int argc, char *argv[]) { const char *file_in_name = NULL; const char *file_out_name = NULL; bool need_save_output = true; + bool blind = true; const struct option long_opts[] = { {"input", required_argument, NULL, 'i'}, {"output", required_argument, NULL, 'o'}, + {"blind", required_argument, NULL, 'b'}, {"save", required_argument, NULL, 's'}, {"help", no_argument, NULL, 'H'}, {0, 0, 0, 0}, }; int opt = -1; - while ((opt = getopt_long(argc, argv, "", long_opts, NULL)) != -1) { + while ((opt = getopt_long (argc, argv, "", long_opts, NULL)) != -1) + { switch (opt) { case 'i': file_in_name = optarg; @@ -68,6 +107,9 @@ int main (int argc, char *argv[]) case 'o': file_out_name = optarg; break; + case 'b': + blind = (strcasecmp (optarg, "false") == 0 ? false : true); + break; case 's': need_save_output = (strcasecmp (optarg, "false") == 0 ? false : true); break; @@ -81,13 +123,15 @@ int main (int argc, char *argv[]) } } - if (optind < argc || argc < 2) { - printf("unknown option %s\n", argv[optind]); + if (optind < argc || argc < 2) + { + printf ("unknown option %s\n", argv[optind]); usage (argv[0]); return -1; } - if (!file_in_name || !file_out_name) { + if (!file_in_name || !file_out_name) + { XCAM_LOG_ERROR ("input/output path is NULL"); return -1; } @@ -95,24 +139,32 @@ int main (int argc, char *argv[]) printf ("Description-----------\n"); printf ("input image file:%s\n", file_in_name); printf ("output file :%s\n", file_out_name); + printf ("blind deblurring:%s\n", blind ? "true" : "false"); printf ("need save file:%s\n", need_save_output ? "true" : "false"); printf ("----------------------\n"); - SmartPtr<CVImageDeblurring> imageDeblurring = new CVImageDeblurring(); - SmartPtr<CVImageSharp> sharp = new CVImageSharp(); - cv::Mat blurred = cv::imread(file_in_name, CV_LOAD_IMAGE_COLOR); - if (blurred.empty()) { + SmartPtr<CVImageSharp> sharp = new CVImageSharp (); + cv::Mat input_image = cv::imread (file_in_name, CV_LOAD_IMAGE_COLOR); + cv::Mat output_image; + if (input_image.empty ()) + { XCAM_LOG_ERROR ("input file read error"); return 0; } - cv::Mat deblurred; - cv::Mat kernel; - imageDeblurring->blind_deblurring (blurred, deblurred, kernel); - float input_sharp = sharp->measure_sharp (blurred); - float output_sharp = sharp->measure_sharp (deblurred); - if (need_save_output) { - cv::imwrite(file_out_name, deblurred); + if (blind) + { + blind_deblurring (input_image, output_image); + } + else + { + non_blind_deblurring (input_image, output_image); + } + float input_sharp = sharp->measure_sharp (input_image); + float output_sharp = sharp->measure_sharp (output_image); + if (need_save_output) + { + cv::imwrite (file_out_name, output_image); } - assert(output_sharp > input_sharp); + XCAM_ASSERT (output_sharp > input_sharp); } diff --git a/tests/test-image-stitching.cpp b/tests/test-image-stitching.cpp index 6d1fa86..ddd765f 100644 --- a/tests/test-image-stitching.cpp +++ b/tests/test-image-stitching.cpp @@ -453,7 +453,6 @@ int main (int argc, char *argv[]) } rectified_view_buf = rectified_view_pool->get_buffer (rectified_view_pool); - for (int i = 0; i < input_count; i++) { ret = file_in[i].open (file_in_name[i], "rb"); CHECK (ret, "open %s failed", file_in_name[i]); @@ -528,27 +527,27 @@ int main (int argc, char *argv[]) ret = image_360->execute (input_buf, output_buf); CHECK (ret, "image_360 stitch execute failed"); - BowlDataConfig config = image_360->get_fisheye_bowl_config (); - sample_generate_top_view (output_buf, top_view_buf, config, top_view_map_table); - sample_generate_rectified_view (output_buf, rectified_view_buf, config, rectified_start_angle, - rectified_end_angle, rectified_view_map_table); - #if HAVE_OPENCV if (need_save_output) { cv::Mat out_mat; convert_to_mat (output_buf, out_mat); writer.write (out_mat); + BowlDataConfig config = image_360->get_fisheye_bowl_config (); cv::Mat top_view_mat; + sample_generate_top_view (output_buf, top_view_buf, config, top_view_map_table); convert_to_mat (top_view_buf, top_view_mat); top_view_writer.write (top_view_mat); cv::Mat rectified_view_mat; + sample_generate_rectified_view (output_buf, rectified_view_buf, config, rectified_start_angle, + rectified_end_angle, rectified_view_map_table); convert_to_mat (rectified_view_buf, rectified_view_mat); rectified_view_writer.write (rectified_view_mat); #if XCAM_TEST_STITCH_DEBUG - dbg_write_image (context, image_360, input_bufs, output_buf, top_view_buf, rectified_view_buf, all_in_one, fisheye_num, input_count); + dbg_write_image (context, image_360, input_bufs, output_buf, top_view_buf, rectified_view_buf, + all_in_one, fisheye_num, input_count); #endif } else #endif diff --git a/tests/test-soft-image.cpp b/tests/test-soft-image.cpp index 64c2d66..578de8e 100644 --- a/tests/test-soft-image.cpp +++ b/tests/test-soft-image.cpp @@ -254,7 +254,7 @@ SoftElement::cv_write_image (char *img_name, char *frame_str, char *idx_str) #endif static int -parse_camera_info (const char *path, uint32_t idx, CameraInfo &info) +parse_camera_info (const char *path, uint32_t idx, CameraInfo &info, uint32_t camera_count) { static const char *instrinsic_names[] = { "intrinsic_camera_front.txt", "intrinsic_camera_right.txt", @@ -282,7 +282,7 @@ parse_camera_info (const char *path, uint32_t idx, CameraInfo &info) info.calibration.extrinsic.trans_x += TEST_CAMERA_POSITION_OFFSET_X; info.angle_range = viewpoints_range[idx]; - info.round_angle_start = (idx * 360.0f / 4.0f) - info.angle_range / 2.0f; + info.round_angle_start = (idx * 360.0f / camera_count) - info.angle_range / 2.0f; return 0; } @@ -428,17 +428,36 @@ ensure_output_format (const char *file_name, const SoftType &type, bool &nv12_ou return XCAM_RETURN_NO_ERROR; } +static bool +check_element (const SoftElements &elements, const uint32_t &idx) +{ + if (idx >= elements.size ()) + return false; + + if (!elements[idx].ptr()) { + XCAM_LOG_ERROR ("SoftElement(idx:%d) ptr is NULL", idx); + return false; + } + + XCAM_FAIL_RETURN ( + ERROR, + elements[idx]->get_width () && elements[idx]->get_height (), + false, + "SoftElement(idx:%d): invalid parameters width:%d height:%d", + idx, elements[idx]->get_width (), elements[idx]->get_height ()); + + return true; +} + static XCamReturn check_elements (const SoftElements &elements) { for (uint32_t i = 0; i < elements.size (); ++i) { - XCAM_ASSERT (elements[i].ptr ()); XCAM_FAIL_RETURN ( ERROR, - elements[i]->get_width () && elements[i]->get_height (), + check_element (elements, i), XCAM_RETURN_ERROR_PARAM, - "SoftElement: invalid parameters index:%d width:%d height:%d", - i, elements[i]->get_width (), elements[i]->get_height ()); + "invalid SoftElement index:%d\n", i); } return XCAM_RETURN_NO_ERROR; @@ -482,13 +501,17 @@ run_stitcher ( if (ret == XCAM_RETURN_BYPASS) break; - stitcher->stitch_buffers (in_buffers, outs[0]->get_buf ()); - if (outs[1].ptr ()) { - CHECK (run_topview (stitcher, outs), "run topview failed"); - } + CHECK ( + stitcher->stitch_buffers (in_buffers, outs[0]->get_buf ()), + "stitch buffer failed."); + + if (save_output) { + if (check_element (outs, 1)) { + CHECK (run_topview (stitcher, outs), "run topview failed"); + } - if (save_output) write_image (ins, outs, nv12_output); + } FPS_CALCULATION (soft - stitcher, XCAM_OBJ_DUR_FRAME_NUM); } while (true); @@ -637,16 +660,16 @@ int main (int argc, char *argv[]) return -1; } - if (!strlen (ins[0]->get_file_name ()) || !strlen (outs[0]->get_file_name ())) { + if (ins.empty () || outs.empty () || + !strlen (ins[0]->get_file_name ()) || !strlen (outs[0]->get_file_name ())) { XCAM_LOG_ERROR ("input or output file name was not set"); usage (argv[0]); return -1; } - printf ("input0 file:\t\t%s\n", ins[0]->get_file_name ()); - printf ("input1 file:\t\t%s\n", ins[1]->get_file_name ()); - printf ("input2 file:\t\t%s\n", ins[2]->get_file_name ()); - printf ("input3 file:\t\t%s\n", ins[3]->get_file_name ()); + for (uint32_t i = 0; i < ins.size (); ++i) { + printf ("input%d file:\t\t%s\n", i, ins[i]->get_file_name ()); + } printf ("output file:\t\t%s\n", outs[0]->get_file_name ()); printf ("input width:\t\t%d\n", input_width); printf ("input height:\t\t%d\n", input_height); @@ -677,6 +700,7 @@ int main (int argc, char *argv[]) switch (type) { case SoftTypeBlender: { + CHECK_EXP (ins.size () >= 2, "blender need 2 input files."); SmartPtr<Blender> blender = Blender::create_soft_blender (); XCAM_ASSERT (blender.ptr ()); blender->set_output_size (output_width, output_height); @@ -708,6 +732,9 @@ int main (int argc, char *argv[]) break; } case SoftTypeStitch: { + CHECK_EXP (ins.size () >= 2 && ins.size () <= 4, "stitcher need at 2~4 input files."); + + uint32_t camera_count = ins.size (); SmartPtr<Stitcher> stitcher = Stitcher::create_soft_stitcher (); XCAM_ASSERT (stitcher.ptr ()); @@ -716,21 +743,23 @@ int main (int argc, char *argv[]) if (!fisheye_config_path) fisheye_config_path = FISHEYE_CONFIG_PATH; - for (uint32_t i = 0; i < 4; ++i) { - if (parse_camera_info (fisheye_config_path, i, cam_info[i]) != 0) { + for (uint32_t i = 0; i < camera_count; ++i) { + if (parse_camera_info (fisheye_config_path, i, cam_info[i], camera_count) != 0) { XCAM_LOG_ERROR ("parse fisheye dewarp info(idx:%d) failed.", i); return -1; } } PointFloat3 bowl_coord_offset; - centralize_bowl_coord_from_cameras ( - cam_info[0].calibration.extrinsic, cam_info[1].calibration.extrinsic, - cam_info[2].calibration.extrinsic, cam_info[3].calibration.extrinsic, - bowl_coord_offset); + if (camera_count == 4) { + centralize_bowl_coord_from_cameras ( + cam_info[0].calibration.extrinsic, cam_info[1].calibration.extrinsic, + cam_info[2].calibration.extrinsic, cam_info[3].calibration.extrinsic, + bowl_coord_offset); + } - stitcher->set_camera_num (4); - for (uint32_t i = 0; i < 4; ++i) { + stitcher->set_camera_num (camera_count); + for (uint32_t i = 0; i < camera_count; ++i) { stitcher->set_camera_info (i, cam_info[i]); } @@ -745,10 +774,13 @@ int main (int argc, char *argv[]) stitcher->set_bowl_config (bowl); stitcher->set_output_size (output_width, output_height); - add_element (outs, "topview", topview_width, topview_height); - if (save_output) + if (save_output) { + add_element (outs, "topview", topview_width, topview_height); elements_open_file (outs, "wb", nv12_output); - run_stitcher (stitcher, ins, outs, nv12_output, save_output, loop); + } + CHECK_EXP ( + run_stitcher (stitcher, ins, outs, nv12_output, save_output, loop) == 0, + "run stitcher failed."); break; } diff --git a/xcore/image_processor.cpp b/xcore/image_processor.cpp index f9914d2..928cbcc 100644 --- a/xcore/image_processor.cpp +++ b/xcore/image_processor.cpp @@ -25,6 +25,7 @@ namespace XCam { void ImageProcessCallback::process_buffer_done (ImageProcessor *processor, const SmartPtr<VideoBuffer> &buf) { + XCAM_UNUSED (processor); XCAM_ASSERT (buf.ptr() && processor); int64_t ts = buf->get_timestamp(); @@ -51,6 +52,7 @@ ImageProcessCallback::process_buffer_failed (ImageProcessor *processor, const Sm void ImageProcessCallback::process_image_result_done (ImageProcessor *processor, const SmartPtr<X3aResult> &result) { + XCAM_UNUSED (processor); XCAM_ASSERT (result.ptr() && processor); int64_t ts = result->get_timestamp(); |