Esempio n. 1
0
/********************************************//**
\brief Compute Inverse Fast Wavelet Transform (iFWT) on 1D array
\param array : input array (1D)
\param filter : name of the filter to use (from TransformationType enum)
\param origLength : original length of the array so the result is cut at this length
\param result : resulting transformed array
\param stop : flag indicating if we need to stop the process or not
\return boolean true if the execution is finished,
        false if the process has been stopped during the execution
***********************************************/
bool FWT::iFastWaveletTransf(const std::vector<float>& array,
                             const TransformationType filter,
                             const int origLength,
                             std::vector<float>& result,
                             bool* stop)
{
    // Get filters
    std::deque<float> h, g;
    compute_wavelet_filters(filter, h, g);
    
    // Reverse filters
    std::deque<float> hRev = h;
    std::reverse(hRev.begin(), hRev.end());
    std::deque<float> gRev = g;
    std::reverse(gRev.begin(), gRev.end());
    
    std::vector<float> inv(array.begin(), array.end());
    
    // iFWT
    int Jmax = log2((float)inv.size()) - 1;
    int Jmin = 0;
    for(int j = Jmin; j <= Jmax; ++j)
    {
        if(*stop)
        {
            return false;
        }
        std::vector<float> Coarse(&inv[0], &inv[pow(2., j)]);
        std::vector<float> Detail(&inv[pow(2., j)], &inv[pow(2.,j+1)]);
        
        // Get Coarse and Detail
        Coarse = cconv(upsampling(Coarse), hRev);
        Detail = cconv(upsampling(Detail), gRev);
        
        for(int k = 0; k < pow(2., j+1); ++k)
        {
            if(*stop)
            {
                return false;
            }
            inv[k] = Coarse[k] + Detail[k];
        }
        
    }
    
    // Remove points so result is origLength length
    int N = pow(2, ceil(log2((float)origLength))) - origLength;
    removePoints(inv, N);
    result = inv;
    return true;
}
Esempio n. 2
0
void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int src_x, int src_y)
{
	assert(src_x >= 0 && src_y >= 0);
	ccv_declare_matrix_signature(sig, a->sig != 0, ccv_sign_with_format(64, "ccv_sample_up(%d,%d)", src_x, src_y), a->sig, 0);
	type = (type == 0) ? CCV_GET_DATA_TYPE(a->type) | CCV_GET_CHANNEL(a->type) : CCV_GET_DATA_TYPE(type) | CCV_GET_CHANNEL(a->type);
	ccv_dense_matrix_t* db = *b = ccv_dense_matrix_renew(*b, a->rows * 2, a->cols * 2, CCV_ALL_DATA_TYPE | CCV_GET_CHANNEL(a->type), type, sig);
	ccv_matrix_return_if_cached(, db);
	int ch = CCV_GET_CHANNEL(a->type);
	int cols0 = a->cols - 1 - src_x;
	int y, x, sy = -1 + src_y, sx = src_x * ch, k;
	int* tab = (int*)alloca((a->cols + src_x + 2) * ch * sizeof(int));
	for (x = 0; x < a->cols + src_x + 2; x++)
		for (k = 0; k < ch; k++)
			tab[x * ch + k] = ((x >= a->cols) ? a->cols * 2 - 1 - x : x) * ch + k;
	unsigned char* buf = (unsigned char*)alloca(3 * db->cols * ch * ccv_max(CCV_GET_DATA_TYPE_SIZE(db->type), sizeof(int)));
	int bufstep = db->cols * ch * ccv_max(CCV_GET_DATA_TYPE_SIZE(db->type), sizeof(int));
	unsigned char* b_ptr = db->data.u8;
	/* why src_y * 2: the same argument as in ccv_sample_down */
#define for_block(_for_get_a, _for_set, _for_get, _for_set_b) \
	for (y = 0; y < a->rows; y++) \
	{ \
		for (; sy <= y + 1 + src_y; sy++) \
		{ \
			unsigned char* row = buf + ((sy + src_y * 2 + 1) % 3) * bufstep; \
			int _sy = (sy < 0) ? -1 - sy : (sy >= a->rows) ? a->rows * 2 - 1 - sy : sy; \
			unsigned char* a_ptr = a->data.u8 + a->step * _sy; \
			if (a->cols == 1) \
			{ \
				for (k = 0; k < ch; k++) \
				{ \
					_for_set(row, k, _for_get_a(a_ptr, k, 0) * (G025 + G075 + G125), 0); \
					_for_set(row, k + ch, _for_get_a(a_ptr, k, 0) * (G025 + G075 + G125), 0); \
				} \
				continue; \
			} \
			if (sx == 0) \
			{ \
				for (k = 0; k < ch; k++) \
				{ \
					_for_set(row, k, _for_get_a(a_ptr, k + sx, 0) * (G025 + G075) + _for_get_a(a_ptr, k + sx + ch, 0) * G125, 0); \
					_for_set(row, k + ch, _for_get_a(a_ptr, k + sx, 0) * (G125 + G025) + _for_get_a(a_ptr, k + sx + ch, 0) * G075, 0); \
				} \
			} \
			/* some serious flaw in computing Gaussian weighting in previous version
			 * specially, we are doing perfect upsampling (2x) so, it concerns a grid like:
			 * XXYY
			 * XXYY
			 * in this case, to upsampling, the weight should be from distance 0.25 and 1.25, and 0.25 and 0.75
			 * previously, it was mistakingly be 0.0 1.0, 0.5 0.5 (imperfect upsampling (2x - 1)) */ \
			for (x = (sx == 0) ? ch : 0; x < cols0 * ch; x += ch) \
			{ \
				for (k = 0; k < ch; k++) \
				{ \
					_for_set(row, x * 2 + k, _for_get_a(a_ptr, x + sx - ch + k, 0) * G075 + _for_get_a(a_ptr, x + sx + k, 0) * G025 + _for_get_a(a_ptr, x + sx + ch + k, 0) * G125, 0); \
					_for_set(row, x * 2 + ch + k, _for_get_a(a_ptr, x + sx - ch + k, 0) * G125 + _for_get_a(a_ptr, x + sx + k, 0) * G025 + _for_get_a(a_ptr, x + sx + ch + k, 0) * G075, 0); \
				} \
			} \
			x_block(_for_get_a, _for_set, _for_get, _for_set_b); \
		} \