void Picture::setPixel(int x, int y, Pixel pix) { if ( x >= width || y >= height ) Picture::out_of_bounds_error(width,height,x,y); if ( channels == 3 ){ image_data(x,y,0,0) = pix.R; image_data(x,y,0,1) = pix.G; image_data(x,y,0,2) = pix.B; } else { image_data(x,y,0,0) = pix.R; } }
Ihandle* IupImage (int width, int height, const unsigned char *pixmap) { Ihandle *n = iupTreeCreateNode(NULL); type(n) = IMAGE_; IupSetfAttribute(n,IUP_WIDTH,"%u", width); IupSetfAttribute(n,IUP_HEIGHT,"%u", height); IupSetAttribute(n,"BPP","8"); IupSetAttribute(n,"CHANNELS","1"); image_data(n) = (char *) malloc (width*height); if (image_data(n) && pixmap) memcpy (image_data(n),pixmap,width*height); return n; }
Pixel Picture::getPixel(int x, int y) { if ( x >= width || y >= height ) Picture::out_of_bounds_error(width,height,x,y); Pixel result; if ( channels == 3 ){ result.R = image_data(x,y,0,0); result.G = image_data(x,y,0,1); result.B = image_data(x,y,0,2); } else{ result.R = result.G = result.B = image_data(x,y,0,0); } return result; }
template <typename PointInT, typename PointOutT> void pcl::AgastKeypoint2D<PointInT, PointOutT>::detectKeypoints (PointCloudOut &output) { // image size const size_t width = input_->width; const size_t height = input_->height; // destination for intensity data; will be forwarded to AGAST std::vector<unsigned char> image_data (width*height); for (size_t row_index = 0; row_index < height; ++row_index) for (size_t col_index = 0; col_index < width; ++col_index) image_data[row_index*width + col_index] = static_cast<unsigned char> (intensity_ ((*input_) (col_index, row_index))); if (!detector_) detector_.reset (new pcl::keypoints::agast::AgastDetector7_12s (width, height, threshold_, bmax_)); if (apply_non_max_suppression_) { pcl::PointCloud<pcl::PointUV> tmp_cloud; detector_->detectKeypoints (image_data, tmp_cloud); pcl::keypoints::internal::AgastApplyNonMaxSuppresion<PointOutT> anms ( image_data, tmp_cloud, detector_, output); } else { pcl::keypoints::internal::AgastDetector<PointOutT> dec ( image_data, detector_, output); } // we do not change the denseness output.is_dense = true; }
explicit image_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) : filename_(filename) , frame_(core::basic_frame::empty()) { auto bitmap = load_image(filename_); FreeImage_FlipVertical(bitmap.get()); core::pixel_format_desc desc; desc.pix_fmt = core::pixel_format::bgra; desc.planes.push_back(core::pixel_format_desc::plane(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), 4)); auto frame = frame_factory->create_frame(this, desc); std::copy_n(FreeImage_GetBits(bitmap.get()), frame->image_data().size(), frame->image_data().begin()); frame->commit(); frame_ = std::move(frame); }
core::mutable_frame make_frame(void* tag, core::frame_factory& frame_factory, std::shared_ptr<AVFrame> video, std::shared_ptr<AVFrame> audio) { const auto pix_desc = video ? pixel_format_desc(static_cast<AVPixelFormat>(video->format), video->width, video->height) : core::pixel_format_desc(core::pixel_format::invalid); auto frame = frame_factory.create_frame(tag, pix_desc); if (video) { for (int n = 0; n < static_cast<int>(pix_desc.planes.size()); ++n) { tbb::parallel_for(0, pix_desc.planes[n].height, [&](int y) { std::memcpy(frame.image_data(n).begin() + y * pix_desc.planes[n].linesize, video->data[n] + y * video->linesize[n], pix_desc.planes[n].linesize); }); } } if (audio) { // TODO This is a bit of a hack frame.audio_data() = std::vector<int32_t>(audio->nb_samples * 8, 0); auto dst = frame.audio_data().data(); auto src = reinterpret_cast<int32_t*>(audio->data[0]); tbb::parallel_for(0, audio->nb_samples, [&](int i) { for (auto j = 0; j < std::min(8, audio->channels); ++j) { dst[i * 8 + j] = src[i * audio->channels + j]; } }); } return frame; }
explicit image_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) : filename_(filename) , frame_(core::draw_frame::empty()) { auto bitmap = load_image(filename_); FreeImage_FlipVertical(bitmap.get()); core::pixel_format_desc desc = core::pixel_format::bgra; desc.planes.push_back(core::pixel_format_desc::plane(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), 4)); auto frame = frame_factory->create_frame(this, desc); std::copy_n(FreeImage_GetBits(bitmap.get()), frame.image_data(0).size(), frame.image_data(0).begin()); frame_ = core::draw_frame(std::move(frame)); CASPAR_LOG(info) << print() << L" Initialized"; }
virtual safe_ptr<basic_frame> receive(int) override { auto format_desc = consumer_->get_video_format_desc(); if(frame_buffer_.size() > 0) { auto frame = frame_buffer_.front(); frame_buffer_.pop(); return last_frame_ = frame; } auto read_frame = consumer_->receive(); if(!read_frame || read_frame->image_data().empty()) return basic_frame::late(); frame_number_++; core::pixel_format_desc desc; bool double_speed = std::abs(frame_factory_->get_video_format_desc().fps / 2.0 - format_desc.fps) < 0.01; bool half_speed = std::abs(format_desc.fps / 2.0 - frame_factory_->get_video_format_desc().fps) < 0.01; if(half_speed && frame_number_ % 2 == 0) // Skip frame return receive(0); desc.pix_fmt = core::pixel_format::bgra; desc.planes.push_back(core::pixel_format_desc::plane(format_desc.width, format_desc.height, 4)); auto frame = frame_factory_->create_frame(this, desc, read_frame->multichannel_view().channel_layout()); bool copy_audio = !double_speed && !half_speed; if (copy_audio) { frame->audio_data().reserve(read_frame->audio_data().size()); boost::copy(read_frame->audio_data(), std::back_inserter(frame->audio_data())); } fast_memcpy(frame->image_data().begin(), read_frame->image_data().begin(), read_frame->image_data().size()); frame->commit(); frame_buffer_.push(frame); if(double_speed) frame_buffer_.push(frame); return receive(0); }
void image_malloc_rand (Image* image, int dims[2]) { int i; image_malloc (image, dims); for (i = 0; i < image_size(image); i++) { image_data(image)[i] = rand_kr() / 32768.0; } }
template <typename PointInT, typename PointOutT, typename IntensityT> void pcl::BriskKeypoint2D<PointInT, PointOutT, IntensityT>::detectKeypoints (PointCloudOut &output) { // image size const int width = int (input_->width); const int height = int (input_->height); // destination for intensity data; will be forwarded to BRISK std::vector<unsigned char> image_data (width*height); for (size_t i = 0; i < image_data.size (); ++i) image_data[i] = static_cast<unsigned char> (intensity_ ((*input_)[i])); pcl::keypoints::brisk::ScaleSpace brisk_scale_space (octaves_); brisk_scale_space.constructPyramid (image_data, width, height); // Check if the template types are the same. If true, avoid a copy. // The PointOutT MUST be registered using the POINT_CLOUD_REGISTER_POINT_STRUCT macro! if (isSamePointType<PointOutT, pcl::PointWithScale> ()) brisk_scale_space.getKeypoints (threshold_, output.points); else { pcl::PointCloud<pcl::PointWithScale> output_temp; brisk_scale_space.getKeypoints (threshold_, output_temp.points); pcl::copyPointCloud<pcl::PointWithScale, PointOutT> (output_temp, output); } // we do not change the denseness output.width = int (output.points.size ()); output.height = 1; output.is_dense = false; // set to false to be sure // 2nd pass to remove the invalid set of 3D keypoints if (remove_invalid_3D_keypoints_) { PointCloudOut output_clean; for (size_t i = 0; i < output.size (); ++i) { PointOutT pt; // Interpolate its position in 3D, as the "u" and "v" are subpixel accurate bilinearInterpolation (input_, output[i].x, output[i].y, pt); // Check if the point is finite if (pcl::isFinite (pt)) output_clean.push_back (output[i]); } output = output_clean; output.is_dense = true; // set to true as there's no keypoint at an invalid XYZ } }
void image_read (Image* image, char* fn) { FILE* fp; int i; char buf[1024]; image_init (image); /* Leaks if image previously used */ fp = fopen (fn, "rb"); if (!fp) return; if (fgets (buf, 1024, fp) == NULL) { printf ("Error reading pfm file\n"); return; } if (strcmp (buf, "Pf\n")) { fclose (fp); printf ("Error reading pfm file\n"); return; } if (fgets (buf, 1024, fp) == NULL) { printf ("Error reading pfm file\n"); return; } if (sscanf (buf, "%d %d", &image->dims[0], &image->dims[1]) != 2) { fclose (fp); printf ("Error reading pfm file\n"); return; } if (fgets (buf, 1024, fp) == NULL) { printf ("Error reading pfm file\n"); return; } if (strcmp (buf, "-1\n")) { fclose (fp); printf ("Error reading pfm file\n"); return; } image_malloc (image, image->dims); for (i = 0; i < image_size(image); i++) { float fv; fread (&fv, sizeof(float), 1, fp); image_data(image)[i] = (double) fv; } fclose (fp); }
void image_write (Image* image, const char* fn) { FILE* fp; int i; fp = fopen (fn, "wb"); if (!fp) return; fprintf (fp, "Pf\n" "%d %d\n" "-1\n", image->dims[0], image->dims[1]); for (i = 0; i < image_size(image); i++) { float fv = (float) image_data(image)[i]; fwrite (&fv, sizeof(float), 1, fp); } fclose (fp); }
bool core::archive::image_cache::update(const history_block& _block) { if (!tree_is_consistent_) { image_vector_t to_add; image_vector_t to_delete; for (const auto& it : _block) { const history_message& message = *it; if (message.is_patch()) to_delete.emplace_back(image_data(message.get_msgid())); else extract_images(message, to_add); } const bool add_result = append_to_file(*tmp_to_add_storage_, to_add); const bool delete_result = append_to_file(*tmp_to_delete_storage_, to_delete); return add_result && delete_result; } const auto end = image_by_msgid_.end(); bool need_to_save_all = false; image_vector_t to_add; for (const auto& it : _block) { const history_message& message = *it; const auto msgid = message.get_msgid(); if (message.is_patch()) { auto to_delete = image_by_msgid_.find(msgid); if (to_delete != end) { need_to_save_all = true; image_by_msgid_.erase(to_delete); } } else { extract_images(message, to_add); } } if (need_to_save_all) { return save_all(); } else if (!to_add.empty()) { archive::storage_mode mode; mode.flags_.write_ = true; mode.flags_.append_ = true; if (!storage_->open(mode)) return false; core::tools::auto_scope lb([this]{ storage_->close(); }); add_images_to_tree(to_add); return serialize_block(*storage_, to_add); } return true; }
cimg_forXY(image_data,x,y){ image_data(x,y,0,0) = img[y*width*3+x*3]; image_data(x,y,0,1) = img[y*width*3+x*3+1]; image_data(x,y,0,2) = img[y*width*3+x*3+2]; }
template <typename PointInT, typename PointOutT, typename KeypointT, typename IntensityT> void pcl::BRISK2DEstimation<PointInT, PointOutT, KeypointT, IntensityT>::compute ( PointCloudOutT &output) { if (!input_cloud_->isOrganized ()) { PCL_ERROR ("[pcl::%s::initCompute] %s doesn't support non organized clouds!\n", name_.c_str ()); return; } // image size const int width = int (input_cloud_->width); const int height = int (input_cloud_->height); // destination for intensity data; will be forwarded to BRISK std::vector<unsigned char> image_data (width*height); for (size_t row_index = 0; row_index < height; ++row_index) { for (size_t col_index = 0; col_index < width; ++col_index) { image_data[row_index*width + col_index] = static_cast<unsigned char> (intensity_ ((*input_cloud_) (col_index, row_index))); } } // Remove keypoints very close to the border size_t ksize = keypoints_->points.size (); std::vector<int> kscales; // remember the scale per keypoint kscales.resize (ksize); // initialize constants static const float log2 = 0.693147180559945f; static const float lb_scalerange = std::log (scalerange_) / (log2); typename std::vector<KeypointT, Eigen::aligned_allocator<KeypointT> >::iterator beginning = keypoints_->points.begin (); std::vector<int>::iterator beginningkscales = kscales.begin (); static const float basic_size_06 = basic_size_ * 0.6f; unsigned int basicscale = 0; if (!scale_invariance_enabled_) basicscale = std::max (static_cast<int> (float (scales_) / lb_scalerange * (log (1.45f * basic_size_ / (basic_size_06)) / log2) + 0.5f), 0); for (size_t k = 0; k < ksize; k++) { unsigned int scale; if (scale_invariance_enabled_) { scale = std::max (static_cast<int> (float (scales_) / lb_scalerange * (log (keypoints_->points[k].size / (basic_size_06)) / log2) + 0.5f), 0); // saturate if (scale >= scales_) scale = scales_ - 1; kscales[k] = scale; } else { scale = basicscale; kscales[k] = scale; } const int border = size_list_[scale]; const int border_x = width - border; const int border_y = height - border; if (RoiPredicate (float (border), float (border), float (border_x), float (border_y), keypoints_->points[k])) { keypoints_->points.erase (beginning + k); kscales.erase (beginningkscales + k); if (k == 0) { beginning = keypoints_->points.begin (); beginningkscales = kscales.begin (); } ksize--; k--; } } // first, calculate the integral image over the whole image: // current integral image std::vector<int> integral; // the integral image //integral (image, integral); int* values = new int[points_]; // for temporary use // resize the descriptors: //output = zeros (ksize, strings_); // now do the extraction for all keypoints: // temporary variables containing gray values at sample points: int t1; int t2; // the feature orientation int direction0; int direction1; unsigned char* ptr = &output.points[0].descriptor[0]; for (size_t k = 0; k < ksize; k++) { int theta; KeypointT &kp = keypoints_->points[k]; const int& scale = kscales[k]; int shifter = 0; int* pvalues = values; const float& x = float (kp.x); const float& y = float (kp.y); if (true) // kp.angle==-1 { if (!rotation_invariance_enabled_) // don't compute the gradient direction, just assign a rotation of 0° theta = 0; else { // get the gray values in the unrotated pattern for (unsigned int i = 0; i < points_; i++) *(pvalues++) = smoothedIntensity (image_data, width, height, integral, x, y, scale, 0, i); direction0 = 0; direction1 = 0; // now iterate through the long pairings const BriskLongPair* max = long_pairs_ + no_long_pairs_; for (BriskLongPair* iter = long_pairs_; iter < max; ++iter) { t1 = *(values + iter->i); t2 = *(values + iter->j); const int delta_t = (t1 - t2); // update the direction: const int tmp0 = delta_t * (iter->weighted_dx) / 1024; const int tmp1 = delta_t * (iter->weighted_dy) / 1024; direction0 += tmp0; direction1 += tmp1; } kp.angle = atan2 (float (direction1), float (direction0)) / float (M_PI) * 180.0f; theta = static_cast<int> ((float (n_rot_) * kp.angle) / (360.0f) + 0.5f); if (theta < 0) theta += n_rot_; if (theta >= int (n_rot_)) theta -= n_rot_; } } else { // figure out the direction: //int theta=rotationInvariance*round((_n_rot*atan2(direction.at<int>(0,0),direction.at<int>(1,0)))/(2*M_PI)); if (!rotation_invariance_enabled_) theta = 0; else { theta = static_cast<int> (n_rot_ * (kp.angle / (360.0)) + 0.5); if (theta < 0) theta += n_rot_; if (theta >= int (n_rot_)) theta -= n_rot_; } } // now also extract the stuff for the actual direction: // let us compute the smoothed values shifter = 0; //unsigned int mean=0; pvalues = values; // get the gray values in the rotated pattern for (unsigned int i = 0; i < points_; i++) *(pvalues++) = smoothedIntensity (image_data, width, height, integral, x, y, scale, theta, i); #ifdef __GNUC__ typedef uint32_t __attribute__ ((__may_alias__)) UINT32_ALIAS; #endif #ifdef _MSC_VER // Todo: find the equivalent to may_alias #define UCHAR_ALIAS uint32_t //__declspec(noalias) #endif // now iterate through all the pairings UINT32_ALIAS* ptr2 = reinterpret_cast<UINT32_ALIAS*> (ptr); const BriskShortPair* max = short_pairs_ + no_short_pairs_; for (BriskShortPair* iter = short_pairs_; iter < max; ++iter) { t1 = *(values + iter->i); t2 = *(values + iter->j); if (t1 > t2) *ptr2 |= ((1) << shifter); // else already initialized with zero // take care of the iterators: ++shifter; if (shifter == 32) { shifter = 0; ++ptr2; } } ptr += strings_; // Account for the scale + orientation; ptr += sizeof (output.points[0].scale); ptr += sizeof (output.points[0].orientation); } // we do not change the denseness output.width = int (output.points.size ()); output.height = 1; output.is_dense = true; // clean-up delete [] values; }
static int vhd_dyn_write(int fd) { struct vhd_footer footer; struct vhd_dyn_header header; uint64_t imgsz; lba_t blk, blkcnt, nblks; uint32_t *bat; void *bitmap; size_t batsz; uint32_t sector; int bat_entries, error, entry; imgsz = image_get_size() * secsz; bat_entries = imgsz / VHD_BLOCK_SIZE; vhd_make_footer(&footer, imgsz, VHD_DISK_TYPE_DYNAMIC, sizeof(footer)); if (sparse_write(fd, &footer, sizeof(footer)) < 0) return (errno); memset(&header, 0, sizeof(header)); be64enc(&header.cookie, VHD_HEADER_COOKIE); be64enc(&header.data_offset, ~0ULL); be64enc(&header.table_offset, sizeof(footer) + sizeof(header)); be32enc(&header.version, VHD_VERSION); be32enc(&header.max_entries, bat_entries); be32enc(&header.block_size, VHD_BLOCK_SIZE); be32enc(&header.checksum, vhd_checksum(&header, sizeof(header))); if (sparse_write(fd, &header, sizeof(header)) < 0) return (errno); batsz = bat_entries * sizeof(uint32_t); batsz = (batsz + VHD_SECTOR_SIZE - 1) & ~(VHD_SECTOR_SIZE - 1); bat = malloc(batsz); if (bat == NULL) return (errno); memset(bat, 0xff, batsz); blkcnt = VHD_BLOCK_SIZE / secsz; sector = (sizeof(footer) + sizeof(header) + batsz) / VHD_SECTOR_SIZE; for (entry = 0; entry < bat_entries; entry++) { blk = entry * blkcnt; if (image_data(blk, blkcnt)) { be32enc(&bat[entry], sector); sector += (VHD_BLOCK_SIZE / VHD_SECTOR_SIZE) + 1; } } if (sparse_write(fd, bat, batsz) < 0) { free(bat); return (errno); } free(bat); bitmap = malloc(VHD_SECTOR_SIZE); if (bitmap == NULL) return (errno); memset(bitmap, 0xff, VHD_SECTOR_SIZE); blk = 0; blkcnt = VHD_BLOCK_SIZE / secsz; error = 0; nblks = image_get_size(); while (blk < nblks) { if (!image_data(blk, blkcnt)) { blk += blkcnt; continue; } if (sparse_write(fd, bitmap, VHD_SECTOR_SIZE) < 0) { error = errno; break; } error = image_copyout_region(fd, blk, blkcnt); if (error) break; blk += blkcnt; } free(bitmap); if (blk != nblks) return (error); if (sparse_write(fd, &footer, sizeof(footer)) < 0) return (errno); return (0); }
static int vmdk_write(int fd) { struct vmdk_header hdr; uint32_t *gt, *gd, *rgd; char *buf, *desc; off_t cur, lim; uint64_t imagesz; lba_t blkofs, blkcnt; size_t gdsz, gtsz; uint32_t sec, cursec; int error, desc_len, n, ngrains, ngts; imagesz = (image_get_size() * secsz) / VMDK_SECTOR_SIZE; memset(&hdr, 0, sizeof(hdr)); le32enc(&hdr.magic, VMDK_MAGIC); le32enc(&hdr.version, VMDK_VERSION); le32enc(&hdr.flags, VMDK_FLAGS_NL_TEST | VMDK_FLAGS_RGT_USED); le64enc(&hdr.capacity, imagesz); le64enc(&hdr.grain_size, grainsz); n = asprintf(&desc, desc_fmt, 1 /*version*/, 0 /*CID*/, (uintmax_t)imagesz /*size*/, "" /*name*/, ncyls /*cylinders*/, nheads /*heads*/, nsecs /*sectors*/); if (n == -1) return (ENOMEM); desc_len = (n + VMDK_SECTOR_SIZE - 1) & ~(VMDK_SECTOR_SIZE - 1); desc = realloc(desc, desc_len); memset(desc + n, 0, desc_len - n); le64enc(&hdr.desc_offset, 1); le64enc(&hdr.desc_size, desc_len / VMDK_SECTOR_SIZE); le32enc(&hdr.ngtes, VMDK_NGTES); sec = desc_len / VMDK_SECTOR_SIZE + 1; ngrains = imagesz / grainsz; ngts = (ngrains + VMDK_NGTES - 1) / VMDK_NGTES; gdsz = (ngts * sizeof(uint32_t) + VMDK_SECTOR_SIZE - 1) & ~(VMDK_SECTOR_SIZE - 1); gd = calloc(1, gdsz); if (gd == NULL) { free(desc); return (ENOMEM); } le64enc(&hdr.gd_offset, sec); sec += gdsz / VMDK_SECTOR_SIZE; for (n = 0; n < ngts; n++) { le32enc(gd + n, sec); sec += VMDK_NGTES * sizeof(uint32_t) / VMDK_SECTOR_SIZE; } rgd = calloc(1, gdsz); if (rgd == NULL) { free(gd); free(desc); return (ENOMEM); } le64enc(&hdr.rgd_offset, sec); sec += gdsz / VMDK_SECTOR_SIZE; for (n = 0; n < ngts; n++) { le32enc(rgd + n, sec); sec += VMDK_NGTES * sizeof(uint32_t) / VMDK_SECTOR_SIZE; } sec = (sec + grainsz - 1) & ~(grainsz - 1); if (verbose) fprintf(stderr, "VMDK: overhead = %ju\n", (uintmax_t)(sec * VMDK_SECTOR_SIZE)); le64enc(&hdr.overhead, sec); be32enc(&hdr.nl_test, VMDK_NL_TEST); gt = calloc(ngts, VMDK_NGTES * sizeof(uint32_t)); if (gt == NULL) { free(rgd); free(gd); free(desc); return (ENOMEM); } gtsz = ngts * VMDK_NGTES * sizeof(uint32_t); cursec = sec; blkcnt = (grainsz * VMDK_SECTOR_SIZE) / secsz; for (n = 0; n < ngrains; n++) { blkofs = n * blkcnt; if (image_data(blkofs, blkcnt)) { le32enc(gt + n, cursec); cursec += grainsz; } } error = 0; if (!error && sparse_write(fd, &hdr, VMDK_SECTOR_SIZE) < 0) error = errno; if (!error && sparse_write(fd, desc, desc_len) < 0) error = errno; if (!error && sparse_write(fd, gd, gdsz) < 0) error = errno; if (!error && sparse_write(fd, gt, gtsz) < 0) error = errno; if (!error && sparse_write(fd, rgd, gdsz) < 0) error = errno; if (!error && sparse_write(fd, gt, gtsz) < 0) error = errno; free(gt); free(rgd); free(gd); free(desc); if (error) return (error); cur = VMDK_SECTOR_SIZE + desc_len + (gdsz + gtsz) * 2; lim = sec * VMDK_SECTOR_SIZE; if (cur < lim) { buf = calloc(1, VMDK_SECTOR_SIZE); if (buf == NULL) error = ENOMEM; while (!error && cur < lim) { if (sparse_write(fd, buf, VMDK_SECTOR_SIZE) < 0) error = errno; cur += VMDK_SECTOR_SIZE; } if (buf != NULL) free(buf); } if (error) return (error); blkcnt = (grainsz * VMDK_SECTOR_SIZE) / secsz; for (n = 0; n < ngrains; n++) { blkofs = n * blkcnt; if (image_data(blkofs, blkcnt)) { error = image_copyout_region(fd, blkofs, blkcnt); if (error) return (error); } } return (image_copyout_done(fd)); }
Billboard::Billboard(const ::si3::ImageData & imaged) { image_data(imaged); }
/* =======================================================================* Public Functions * =======================================================================*/ void s_ncc_fft_compile (FATM_Options* fopt) { fftw_plan pat_plan; double* temp; int i, j; Image_Rect* prv = &fopt->pat_rect_valid; fftw_iodim fftw_dims[2]; int fft_nx = fopt->sig_rect_scan.dims[1]; /* In fftw3, nx is rows */ int fft_ny = fopt->sig_rect_scan.dims[0]; /* In fftw3, ny is cols */ /* Allocate memory */ S_Ncc_Fft_Data* udp = (S_Ncc_Fft_Data*) malloc (sizeof(S_Ncc_Fft_Data)); fopt->alg_data = (void*) udp; /* Alloc memory for integral images */ s_ncc_fft_scorewin_alloc (fopt); /* Compute pattern statistics */ // s_pattern_statistics (&udp->p_stats, fopt); /* Alloc memory for fft of pat */ udp->pat_fft = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * fft_nx * (fft_ny/2+1)); memset (udp->pat_fft, 0, sizeof(fftw_complex) * fft_nx * (fft_ny/2+1)); /* Copy pattern into fft memory. Flip it so that convolution becomes correlation */ temp = (double*) udp->pat_fft + (fft_nx-1) * (2*(fft_ny/2+1)) + fft_ny - 1; for (j = 0; j < prv->dims[0]; j++) { for (i = 0; i < prv->dims[1]; i++) { *temp-- = image_data(&fopt->pat)[image_index(prv->dims, j, i)]; } temp -= (2*(fft_ny/2+1)) - prv->dims[1]; } /* Peform fft */ pat_plan = fftw_plan_dft_r2c_2d (fft_nx, fft_ny, (double*) udp->pat_fft, udp->pat_fft, FFTW_ESTIMATE); fftw_execute (pat_plan); fftw_destroy_plan (pat_plan); /* Debugging info */ dump_fft (udp->pat_fft, fft_nx, fft_ny, "pat_fft.txt"); /* Alloc memory for fft of sig */ udp->sig_fft = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * fft_nx * (fft_ny/2+1)); /* Create plan for sig -> sig_fft */ fftw_dims[0].n = fft_nx; fftw_dims[0].is = fopt->sig.dims[0]; fftw_dims[0].os = (fft_ny/2+1); fftw_dims[1].n = fft_ny; fftw_dims[1].is = 1; fftw_dims[1].os = 1; /* NOTE: Using FFTW_MEASURE overwrites input. So I need to allocate a temporary array. */ udp->sig_fftw3_plan = fftw_plan_guru_dft_r2c ( 2, fftw_dims, 0, 0, (double*) fopt->sig.data, udp->sig_fft, FFTW_ESTIMATE | FFTW_UNALIGNED | FFTW_PRESERVE_INPUT); if (udp->sig_fftw3_plan == 0) { printf ("Error: couldn't make plan\n"); } printf ("SRS: %d %d\n", fopt->sig_rect_scan.dims[0], fopt->sig_rect_scan.dims[1]); printf ("SIG: %d %d\n", fopt->sig.dims[0], fopt->sig.dims[1]); /* Alloc memory for temporary score */ udp->padded_score = (double*) fftw_malloc (sizeof(double) * fft_nx * fft_ny); /* Create plan for pat_fft * sig_fft -> score */ udp->sco_fftw3_plan = fftw_plan_dft_c2r_2d (fft_nx, fft_ny, udp->sig_fft, udp->padded_score, FFTW_MEASURE); if (udp->sco_fftw3_plan == 0) { printf ("Error: couldn't make plan\n"); } }