~WardAlignment() { for(unsigned int i=0; i<luminance.size(); i++) { delete luminance[i]; } for(unsigned int i=0; i<img1_v.size(); i++) { delete img1_v[i]; } for(unsigned int i=0; i<img2_v.size(); i++) { delete img2_v[i]; } for(unsigned int i=0; i<tb1_v.size(); i++) { delete tb1_v[i]; } for(unsigned int i=0; i<tb2_v.size(); i++) { delete tb2_v[i]; } for(unsigned int i=0; i<eb2_shifted_v.size(); i++) { delete eb2_shifted_v[i]; } for(unsigned int i=0; i<tb2_shifted_v.size(); i++) { delete tb2_shifted_v[i]; } }
/** * @brief Double creates an std::vector which contains img1 and img2; this is for filters input. * @param img1 is a pointer to a pic::Image * @param img2 is a pointer to a pic::Image * @return It returns an std::vector which contains img1 and img2. */ PIC_INLINE ImageVec Double(Image *img1, Image *img2) { ImageVec ret; ret.push_back(img1); ret.push_back(img2); return ret; }
/** * @brief Triple creates an std::vector which contains img1, img2, and img3; this is for filters input. * @param img1 is a pointer to a pic::Image * @param img2 is a pointer to a pic::Image * @param img3 is a pointer to a pic::Image * @return It returns an std::vector which contains img1, img2, and img3. */ PIC_INLINE ImageVec Triple(Image *img1, Image *img2, Image *img3) { ImageVec ret; ret.push_back(img1); ret.push_back(img2); ret.push_back(img3); return ret; }
/** * @brief Triple creates an std::vector which contains img1, img2, img3, and img4; this is for filters input. * @param img1 is a pointer to a pic::Image * @param img2 is a pointer to a pic::Image * @param img3 is a pointer to a pic::Image * @param img4 is a pointer to a pic::Image * @return It returns an std::vector which contains img1, img2, img3, and img4. */ PIC_INLINE ImageVec Quad(Image *img1, Image *img2, Image *img3, Image *img4) { ImageVec ret; ret.push_back(img1); ret.push_back(img2); ret.push_back(img3); ret.push_back(img4); return ret; }
/** * @brief AddAlpha * @param imgIn * @param imgOut * @param value * @return */ static Image *AddAlpha(Image *imgIn, Image *imgOut, float value) { //Create an alpha channel Image *alpha = new Image(imgIn->frames, imgIn->width, imgIn->height, 1); *alpha = value; //Add the channel to the image ImageVec src; src.push_back(imgIn); src.push_back(alpha); FilterCombine filterC; imgOut = filterC.Process(src, imgOut); delete alpha; return imgOut; }
/** * @brief ExecuteTest * @param nameIn * @param nameOut * @return */ static Image *ExecuteTest(std::string nameIn, std::string nameOut) { Image imgIn(nameIn); FilterChannel filter(0); Image *outR = filter.Process(Single(&imgIn), NULL); filter.setChannel(1); Image *outG = filter.Process(Single(&imgIn), NULL); filter.setChannel(2); Image *outB = filter.Process(Single(&imgIn), NULL); ImageVec src; src.push_back(outR); src.push_back(outG); src.push_back(outB); FilterCombine filterC; Image *ret = filterC.Process(src, NULL); ret->Write(nameOut); return ret; }
void FilterCombine::ProcessBBox(Image *dst, ImageVec src, BBox *box) { for(int p = box->z0; p < box->z1; p++) { for(int j = box->y0; j < box->y1; j++) { for(int i = box->x0; i < box->x1; i++) { int c = p * dst->tstride + j * dst->ystride + i * dst->xstride; int k2 = 0; for(unsigned int im = 0; im < src.size(); im++) { int c2 = p * src[im]->tstride + j * src[im]->ystride + i * src[im]->xstride; for(int k = 0; k < src[im]->channels; k++) { dst->data[c + k2] = src[im]->data[c2 + k]; k2++; } } } } } }
/** * @brief ProcessBBox * @param dst * @param src * @param box */ void ProcessBBox(Image *dst, ImageVec src, BBox *box) { if(src.size()!=2) { return; } int channels = dst->channels; for(int i = box->y0; i < box->y1; i++) { for(int j = box->x0; j < box->x1; j++) { float *tmp_src0 = (*src[0])(j, i); float *tmp_src1 = (*src[1])(j, i); float *tmp_dst = (*dst )(j, i); for(int k = 0; k < channels; k++) { tmp_dst[k] = fabsf(tmp_src0[k] - tmp_src1[k]); } } } }
PIC_INLINE void FilterGuided::ProcessBBox(Image *dst, ImageVec src, BBox *box) { Image *I, *p; if(src.size() == 2) { p = src[0]; if(src[1] != NULL) { I = src[1]; } else { I = src[0]; } } else { I = src[0]; p = src[0]; } if(I->channels == 3) { Process3Channel(I, p, dst, box); } else { Process1Channel(I, p, dst, box); } }
/** * @brief GetExpShift computes the shift vector for moving an img1 onto img2 * @param img1 * @param img2 * @param shift_bits * @return */ Eigen::Vector2i GetExpShift(Image *img1, Image *img2, int shift_bits = 6) { if(img1 == NULL || img2 == NULL) { return Eigen::Vector2i(0, 0.0); } if(!img1->SimilarType(img2)) { return Eigen::Vector2i(0, 0); } Image *L1, *L2; if(img1->channels == 1) { L1 = img1; } else { L1 = FilterLuminance::Execute(img1, NULL, LT_WARD_LUMINANCE); luminance.push_back(L1); } if(img2->channels == 1) { L2 = img2; } else { L2 = FilterLuminance::Execute(img2, NULL, LT_WARD_LUMINANCE); luminance.push_back(L2); } int min_coord = MIN(L1->width, L1->height); if(min_coord < (1 << shift_bits)) { shift_bits = MAX(log2(min_coord) - 1, 1); } Eigen::Vector2i cur_shift, ret_shift; cur_shift = Eigen::Vector2i(0, 0); ret_shift = Eigen::Vector2i(0, 0); Image *sml_img1 = NULL; Image *sml_img2 = NULL; while(shift_bits > 0) { float scale = powf(2.0f, float(-shift_bits)); sml_img1 = FilterDownSampler2D::Execute(L1, NULL, scale); sml_img2 = FilterDownSampler2D::Execute(L2, NULL, scale); //tracking memory img1_v.push_back(sml_img1); img2_v.push_back(sml_img2); int width = sml_img1->width; int height = sml_img1->height; int n = width * height; //Computing the median threshold mask bool *tb1 = MTB(sml_img1, NULL); bool *eb1 = &tb1[n]; bool *tb2 = MTB(sml_img2, NULL); bool *eb2 = &tb2[n]; //tracking memory tb1_v.push_back(tb1); tb2_v.push_back(tb2); int min_err = n; bool *tb2_shifted = new bool[n]; bool *eb2_shifted = new bool[n]; tb2_shifted_v.push_back(tb2_shifted); eb2_shifted_v.push_back(eb2_shifted); for(int i = -1; i <= 1; i++) { for(int j = -1; j <= 1; j++) { int xs = cur_shift[0] + i; int ys = cur_shift[1] + j; BufferShift(tb2_shifted, tb2, xs, ys, width, height, 1, 1); BufferShift(eb2_shifted, eb2, xs, ys, width, height, 1, 1); int err = 0; for(int k=0; k<n; k++) { bool diff_b = tb1[k] ^ tb2_shifted[k]; diff_b = diff_b & eb1[k]; diff_b = diff_b & eb2_shifted[k]; if(diff_b) { err++; } } if(err < min_err) { ret_shift[0] = xs; ret_shift[1] = ys; min_err = err; } } } shift_bits--; cur_shift[0] = ret_shift[0] * 2; cur_shift[1] = ret_shift[1] * 2; } return cur_shift; }
/** * @brief Single creates an std::vector which contains img; this is for filters input. * @param img is a pointer to a pic::Image * @return It returns an std::vector which contains img. */ PIC_INLINE ImageVec Single(Image *img) { ImageVec ret; ret.push_back(img); return ret; }
PIC_INLINE void FilterBilateral2DF::ProcessBBox(Image *dst, ImageVec src, BBox *box) { int channels = dst->channels; //Filtering Image *edge, *base; if(src.size() > 1) { //Joint/Cross Bilateral Filtering base = src[0]; edge = src[1]; } else { base = src[0]; edge = src[0]; } for(int j = box->y0; j < box->y1; j++) { for(int i = box->x0; i < box->x1; i++) { //Convolution kernel float *dst_data = (*dst)(i, j); float *data_edge = (*edge)(i, j); Arrayf::assign(0.0f, dst_data, channels); float sum = 0.0f; for(int k = 0; k < pg->kernelSize; k++) { int cj = j + k - pg->halfKernelSize; for(int l = 0; l < pg->kernelSize; l++) { int ci = i + l - pg->halfKernelSize; //Spatial weight float G1 = pg->coeff[k] * pg->coeff[l]; //Range weight float *cur_edge = (*edge)(ci, cj); float tmp = Arrayf::distanceSq(data_edge, cur_edge, edge->channels); float G2 = expf(-tmp / sigma_r_sq_2); //Weight float weight = G1 * G2; //filter float *base_data_cur = (*base)(ci, cj); for(int m = 0; m < channels; m++) { dst_data[m] += base_data_cur[m] * weight; } sum += weight; } } //normalization if(sum > 0.0f) { Arrayf::div(dst_data, channels, sum); } else { float *base_data = (*base)(i, j); Arrayf::assign(base_data, channels, dst_data); } } } }