📄 rdwt.c
字号:
int QccWAVWaveletRedundantDWT2DSubsample(const QccMatrix *input_matrices, QccMatrix output_matrix, int num_rows, int num_cols, int num_scales, int subsample_pattern_row, int subsample_pattern_col, const QccWAVWavelet *wavelet){ int subband; int num_subbands; int index_skip; int index_offset_row; int index_offset_col; int subband_row_offset; int subband_col_offset; int subband_num_rows; int subband_num_cols; int row; int col; int row_index; int col_index; int baseband_phase_group_size; QccWAVSubbandPyramid subband_pyramid; if (input_matrices == NULL) return(0); if (output_matrix == NULL) return(0); QccWAVSubbandPyramidInitialize(&subband_pyramid); subband_pyramid.num_rows = num_rows; subband_pyramid.num_cols = num_cols; subband_pyramid.num_levels = num_scales; num_subbands = QccWAVSubbandPyramidNumLevelsToNumSubbands(num_scales); baseband_phase_group_size = (1 << num_scales); if (subsample_pattern_row > (baseband_phase_group_size - 1)) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT1DSubsample): subband_pattern_row can take on only values 0 to %d for a transform of %d scales", baseband_phase_group_size - 1, num_scales); return(1); } if (subsample_pattern_col > (baseband_phase_group_size - 1)) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT1DSubsample): subband_pattern_col can take on only values 0 to %d for a transform of %d scales", baseband_phase_group_size - 1, num_scales); return(1); } for (subband = 0; subband < num_subbands; subband++) { if (QccWAVSubbandPyramidSubbandSize(&subband_pyramid, subband, &subband_num_rows, &subband_num_cols)) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT2DSubsample): Error calling QccWAVSubbandPyramidSubbandSize()"); return(1); } if (QccWAVSubbandPyramidSubbandOffsets(&subband_pyramid, subband, &subband_row_offset, &subband_col_offset)) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT2DSubsample): Error calling QccWAVSubbandPyramidSubbandSize()"); return(1); } QccWAVWaveletRedundantDWT2DSubsampleGetPattern(subband, num_scales, subsample_pattern_row, subsample_pattern_col, &index_skip, &index_offset_row, &index_offset_col, wavelet); for (row = 0; row < subband_num_rows; row++) for (col = 0; col < subband_num_cols; col++) { if (wavelet->boundary == QCCWAVWAVELET_BOUNDARY_SYMMETRIC_EXTENSION) { row_index = QccFilterCalcSymmetricExtension(row * index_skip + index_offset_row, num_rows, QCCFILTER_SYMMETRICWHOLE); col_index = QccFilterCalcSymmetricExtension(col * index_skip + index_offset_col, num_cols, QCCFILTER_SYMMETRICWHOLE); } else { row_index = QccMathModulus(row * index_skip + index_offset_row, num_rows); col_index = QccMathModulus(col * index_skip + index_offset_col, num_cols); } output_matrix[subband_row_offset + row] [subband_col_offset + col] = input_matrices[subband][row_index][col_index]; } } return(0);}/* int QccWAVWaveletInverseRedundantDWT2D(const QccMatrix *input_matrices, QccMatrix output_matrix, int num_rows, int num_cols, int num_scales, const QccWAVWavelet *wavelet) { QccWAVSubbandPyramid subband_pyramid; QccWAVSubbandPyramidInitialize(&subband_pyramid); subband_pyramid.matrix = output_matrix; subband_pyramid.num_levels = num_scales; subband_pyramid.num_rows = num_rows; subband_pyramid.num_cols = num_cols; if (QccWAVWaveletRedundantDWT2DSubsample(input_matrices, output_matrix, num_rows, num_cols, num_scales, wavelet)) { QccErrorAddMessage("(QccWAVWaveletInverseRedundantDWT2D): Error calling QccWAVWaveletRedundantDWT2DSubsample()"); return(1); } if (QccWAVSubbandPyramidInverseDWT(&subband_pyramid, wavelet)) { QccErrorAddMessage("(QccWAVWaveletInverseRedundantDWT2D): Error calling QccWAVSubbandPyramidInverseDWT()"); return(1); } return(0); }*/static int QccWAVWaveletInverseRedundantDWT2DRecursion(QccWAVRDWTSubband *input_subbands, QccWAVRDWTSubband *output_subband, int num_scales, const QccWAVWavelet *wavelet){ int return_value = 0; QccWAVRDWTSubband baseband[4]; QccWAVRDWTSubband *new_input_subbands[4] = {NULL, NULL, NULL, NULL}; int num_subbands; int subband; int polyphase; num_subbands = QccWAVSubbandPyramidNumLevelsToNumSubbands(num_scales - 1); if (num_scales != 1) { for (subband = 0; subband < num_subbands; subband++) { if (QccWAVRDWTLWT2D(&input_subbands[subband], output_subband)) { QccErrorAddMessage("(QccWAVWaveletInverseRedundantDWT2DRecursion): Error calling QccWAVRDWTLWT2D()"); goto Error; } QccWAVRDWTSubbandCopy(&input_subbands[subband], output_subband); } for (polyphase = 0; polyphase < 4; polyphase++) { QccWAVRDWTSubbandSetInfo(&baseband[polyphase], output_subband, polyphase); if ((new_input_subbands[polyphase] = (QccWAVRDWTSubband *) malloc(sizeof(QccWAVRDWTSubband) * num_subbands)) == NULL) { QccErrorAddMessage("(QccWAVWaveletInverseRedundantDWT2DRecursion): Error allocating memory"); goto Error; } for (subband = 0; subband < num_subbands; subband++) QccWAVRDWTSubbandSetInfo(&new_input_subbands [polyphase][subband], &input_subbands[subband], polyphase); } for (polyphase = 0; polyphase < 4; polyphase++) if (QccWAVWaveletInverseRedundantDWT2DRecursion(new_input_subbands [polyphase], &baseband[polyphase], num_scales - 1, wavelet)) { QccErrorAddMessage("(QccWAVWaveletInverseRedundantDWT2DRecursion): Error calling QccWAVWaveletInverseRedundantDWT2DRecursion()"); goto Error; } if (QccWAVRDWTInverseLWT2D(output_subband, &input_subbands[0])) { QccErrorAddMessage("(QccWAVWaveletInverseRedundantDWT1D): Error calling QccWAVRDWTInverseLWT2D()"); goto Error; } } if (QccWAVRDWTSynthesis2D(&input_subbands[0], &input_subbands[3*num_scales - 2], &input_subbands[3*num_scales - 1], &input_subbands[3*num_scales], output_subband, wavelet)) { QccErrorAddMessage("(QccWAVWaveletInverseRedundantDWT2DRecursion): Error calling QccWAVRDWTSynthesis2D()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: for (polyphase = 0; polyphase < 4; polyphase++) if (new_input_subbands[polyphase] != NULL) QccFree(new_input_subbands[polyphase]); return(return_value);}int QccWAVWaveletInverseRedundantDWT2D(const QccMatrix *input_matrices, QccMatrix output_matrix, int num_rows, int num_cols, int num_scales, const QccWAVWavelet *wavelet){ int return_value = 0; int max_scales; int subband; int num_subbands; QccWAVRDWTSubband *subbands = NULL; QccWAVRDWTSubband temp_subband; num_subbands = QccWAVSubbandPyramidNumLevelsToNumSubbands(num_scales); if (input_matrices == NULL) return(0); if (output_matrix == NULL) return(0); if (wavelet == NULL) return(0); if (num_scales <= 0) return(0); max_scales = (int)QccMathMin(floor(QccMathLog2(num_rows)), floor(QccMathLog2(num_cols))); if (max_scales < num_scales) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT2D): %d transform scales not supported for size %dx%d matrices - use %d or fewer scales", num_scales, num_cols, num_rows, max_scales); goto Error; } if ((subbands = (QccWAVRDWTSubband *) malloc(num_subbands * sizeof(QccWAVRDWTSubband))) == NULL) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT2D): Error allocating memory"); goto Error; } for (subband = 0; subband < num_subbands; subband++) { if ((subbands[subband].matrix = QccMatrixAlloc(num_rows, num_cols)) == NULL) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT2D): Error calling QccMatrixAlloc()"); goto Error; } if (QccMatrixCopy(subbands[subband].matrix, input_matrices[subband], num_rows, num_cols)) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT2D): Error calling QccMatrixCopy()"); goto Error; } subbands[subband].subband_num_rows = num_rows; subbands[subband].subband_num_cols = num_cols; subbands[subband].subband_row_origin = 0; subbands[subband].subband_col_origin = 0; } temp_subband.matrix = output_matrix; temp_subband.subband_num_rows = num_rows; temp_subband.subband_num_cols = num_cols; temp_subband.subband_row_origin = 0; temp_subband.subband_col_origin = 0; if (QccWAVWaveletInverseRedundantDWT2DRecursion(subbands, &temp_subband, num_scales, wavelet)) { QccErrorAddMessage("(QccWAVWaveletInverseRedundantDWT2D): Error calling QccWAVWaveletInverseRedundantDWT2DRecursion()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: if (subbands != NULL) { for (subband = 0; subband < num_subbands; subband++) QccMatrixFree(subbands[subband].matrix, num_rows); QccFree(subbands); } return(return_value);}int QccWAVWaveletRedundantDWT2DCorrelationMask(const QccMatrix *input_matrices, QccMatrix output_matrix, int num_rows, int num_cols, int num_scales, int start_scale, int stop_scale){ int row, col; int scale; int subband_orientation; int current_subband; double correlation; double max; if (input_matrices == NULL) return(0); if (output_matrix == NULL) return(0); if ((start_scale < 0) || (start_scale > num_scales - 1) || (stop_scale < 0) || (stop_scale > num_scales - 1)) { QccErrorAddMessage("(QccWAVWaveletRedundantDWT2DCorrelationMask): Invalid stop and/or start scale specified"); return(1); } for (scale = start_scale; scale <= stop_scale; scale++) if (input_matrices[scale] == NULL) return(0); for (row = 0; row < num_rows; row++) for (col = 0; col < num_cols; col++) { output_matrix[row][col] = 0; for (subband_orientation = 1; subband_orientation <= 3; subband_orientation++) { correlation = 1.0; for (scale = start_scale; scale <= stop_scale; scale++) { current_subband = subband_orientation + 3 * scale; correlation *= fabs(input_matrices[current_subband][row][col]); } output_matrix[row][col] += correlation; } } max = QccMatrixMaxValue(output_matrix, num_rows, num_cols); for (row = 0; row < num_rows; row++) for (col = 0; col < num_cols; col++) output_matrix[row][col] /= max; return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -