请教各位大神未定义函数build_km_tree,下面有代码,我不咋清楚对错,不过运行不了。谢谢大家啦!

BEIWEIM 2020-09-08 04:05:47
f/*=================================================================
* syntax: T = build_km_tree(I, M, b, t, L, n); OR T = build_km_tree(I, M, b, t, L);
*
* build_km_tree - build km-tree matrix from image
*
* Input: - I: X-by-Y intensity image
* - M: patch size (length of edge)
* - L: number of dictionary layers. This parameter is limited
* such that the average number of patches in a leafnode is
* greater than five
* - b: branching factor
* - t: number of training patches
* - n: normalization (true or false), defaults to false
*
* Output: - T: MMl-by-K matrix where l is the number of layers
* in the image (1 for grayscale and 3 for RGB)
* and K is the number of nodes in the tree.
*
* Author: Anders Dahl, abda@dtu.dk, december 2015.
*=================================================================*/

#include "mex.h"
#include <stdio.h>
#include <math.h>
#include "matrix.h"
#include <vector>
#include <algorithm>

#include <iostream>
using namespace std;

// struct for image
struct im_st
{
double *im_data; // pointer to image data
int rows, cols, layers, n_pix; // rows, cols and layers are the image dimensions and n_pix = rows*cols
};

// struct for the tree
struct tree_st
{
double *tree_data;
int n_dim, n_nodes, branch_fac, M, Mh;
};

// struct for image patches
struct im_patch
{
double *patch_data; // pointer to the data
int idx; // id used for sorting the patches according to the tree
bool operator<(const im_patch& rhs) const {return idx < rhs.idx;} // operator needed for sorting
};


// Function for sampling patches from the image into the patch arrays
// inputs reference to the image struct, tree struct, patch struct and position of the sampling coordinate.
// There is no check if the sampling is outside the image
void sample_patch(im_st& im, tree_st& tree, im_patch& patch, int r_im, int c_im, bool normalize)
{
int id_l, id_r, id_i; // iterators for looking up image data
int id_p = 0; // iterator for looking up patch data
double sum_sq = 0, pix_val; // variables for normalization

for ( int l = 0; l < im.layers; l++ ){ // image is sampled by three nested loops
id_l = im.n_pix*l;
for ( int i = c_im-tree.Mh; i <= c_im+tree.Mh; i++ ){
id_r = id_l + i*im.rows;
for ( int j = r_im-tree.Mh; j <= r_im+tree.Mh; j++ ){
id_i = id_r + j;
pix_val = *(im.im_data + id_i);
*(patch.patch_data + id_p) = pix_val;
sum_sq += pix_val*pix_val;
id_p++;
}
}
}

if ( normalize ){ // normalization to unit length
double inv_sq = 1;
if ( sum_sq > 0 ){
inv_sq = 1/sqrt(sum_sq); // divide by sum of squares
}
for ( int i = 0; i < tree.n_dim; i++ ){
*(patch.patch_data + i) = (*(patch.patch_data + i))*inv_sq;
}
}


}


// function for randomly permuted set of indices
// n is the numbers to choose from, n_set is the number of random indices
// that is returned. Returns a vector of indices
vector<int> randperm( int n, int n_set ) {
if ( n_set > n ){ // check if n_set exceeds n
n_set = n;
}

vector<int> rid;
rid.reserve(n); // vector of indices
for ( int i = 0; i < n; i++ ){ // set all indices in order
rid.push_back(i);
}

int t, id; // place holders for id and temporary number
int r_max = RAND_MAX; // maximum random number
for ( int i = 0; i < n_set; i++ ){
// choose a random number between i and n-1 and swap place between i and id
if ( LONG_MAX > RAND_MAX && n-i-1>RAND_MAX ){ // not enough with a random integer up til RAND_MAX
id = ((rand()*(r_max+1)+rand()) % (n-i)) + i;
}
else{
id = (rand() % (n-i)) + i;
}
t = rid[id];
rid[id] = rid[i];
rid[i] = t;
}
rid.resize(n_set); // set size to n_set
return rid;
}


// copy values from a patch array into the tree array at node
void set_values(tree_st& tree, im_patch& patch, int node){
int idx = tree.n_dim*node;
for ( int i = 0; i < tree.n_dim; i++ ){
*(tree.tree_data + idx) = *(patch.patch_data + i);
idx++;
}
}

// add values to vector of cluster center points
void add_values(vector<double>& center_sum, im_patch& patch, int id, int n_dim){
int idx = n_dim*id;
for ( int i = 0; i < n_dim; i++ ){
center_sum[idx] += *(patch.patch_data + i);
idx++;
}
}

// estimates the squared Euclidian distance between an image patch and a tree node
double get_dist(tree_st& tree, im_patch& patch, int node)
{
double d = 0, tmp;
int id = tree.n_dim*node;

for ( int i = 0; i < tree.n_dim; i++ ){
tmp = *(tree.tree_data + id) - *(patch.patch_data + i);
d += tmp*tmp;
id++;

}

return d;
}

// k-means-function taking a reference to the vector of image patches and a
// tree struct as input f and t gives the image patches that should be clustered.
// node is the first node in the tree included in the clustering
void k_means( vector<im_patch>& patches, tree_st& tree, int f, int t, int node )
{
// vectors holding the sum of values in the cluster and a vector containing the change
vector<double> centSum(tree.branch_fac*tree.n_dim), centChange(tree.branch_fac);
vector<int> centCount(tree.branch_fac); // vector for counting the number of points in a cluster
double min_d, d, tmp;//, diff; // variables for clustering
// variables for cluster id and index of previous cluseter, which will be overwritten by new cluster id
int id = 0, id_in = patches[f].idx;

if ( t-f > tree.branch_fac ){ // check if there are enough point to carry out the clustering
// initialize the center positions
for ( int i = 0; i < tree.branch_fac; i++ ){
set_values(tree, patches[f+i], node+i);
}

// run clutering for 20 iterations - only little change happens after 10 iterations
for ( int n_run = 0; n_run < 30; n_run++){

for ( int i = f; i < t; i++ ){ // go through the patches from f to t
min_d = get_dist(tree, patches[i], node); // initially set min distance and id to the first
id = 0;
for ( int j = 1; j < tree.branch_fac; j++ ){ // run throgh the other points
d = get_dist(tree, patches[i], node + j); // get the distance
if ( d < min_d ){ // if the this cluster is closer set this as min distance
min_d = d;
id = j;
}
}
add_values(centSum, patches[i], id, tree.n_dim); // add the patch to the closest cluster
centCount[id]++; // count the extra patch
// update the idx to the child idx - note that all layers start with idx = 0
patches[i].idx = (id + id_in*tree.branch_fac);
}

// update the clusters in the tree and calculate the center change (not used for anything)
id = node*tree.n_dim;
int id_c = 0;

for ( int i = 0; i < tree.branch_fac; i++ ){ // go through all new clusters
if ( centCount[i] == 0 ){
centCount[i] = 1;
}
for ( int j = 0; j < tree.n_dim; j++ ){ // go through cluster pixels
tmp = centSum[id_c]/centCount[i];
//diff = (tmp - *(tree.tree_data + id)); // for calculating center change
//centChange[i] += diff*diff;
*(tree.tree_data + id) = tmp;
id_c++;
id++;
}
}

// set counter and sum to zero
fill(centSum.begin(), centSum.end(), 0);
fill(centCount.begin(), centCount.end(),0);
fill(centChange.begin(), centChange.end(), 0);
}
}
}

// runs through the patches vector to find the last element with id
int get_to( vector<im_patch>& patches, int id )
{
int to = 0;
for ( int i = 0; i < patches.size(); i++ ){
if ( patches[i].idx == id ){
to = i;
}
}
return to+1;
}

// Main function for building the km-tree. Takes the image and tree struct
// and the number of training patches as argument
void build_km_tree ( im_st& im, tree_st& tree, int n_train, bool normalize ) {
// allocate memory for the image patches
double* im_patch_data = new double[n_train*tree.M*tree.M*im.layers];

int rows_c = im.rows-tree.M+1, cols_c = im.cols-tree.M+1; // number of rows and cols within sampling area
int n_im_patches = rows_c*cols_c; // number of pixels in the image for sampling - inside boundary

// checks that the number of training patches is not exceeding the number of pixels in the sample area
if ( n_im_patches < n_train ){
n_train = n_im_patches;
}

vector<int> r_id = randperm(n_im_patches, n_train); // indices of random patches

vector<im_patch> patches; // vector of image patches
patches.resize(n_train); // allocate memory

int r, c, idx = 0; // variables used for sampling the image
// sample image patches
for (int i = 0; i < n_train; i++ )
{
c = r_id[i]/rows_c; // column is floored because of int
r = r_id[i]-c*rows_c; // row is rest after column
patches[i].idx = 0; // inital id is 0
patches[i].patch_data = im_patch_data + idx; // pointer to patch memory
sample_patch(im, tree, patches[i], r + tree.Mh, c + tree.Mh, normalize); // sampel in image with added boundary
idx += tree.
...全文
185 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
青蛙工作室 2020-09-25
  • 打赏
  • 举报
回复
我只承认容易阅读的汉字注释,豆芽文注释读起来太费劲。 自定义的函数,运行时出错,说明能通过编译,那就更难找问题了。 既然能运行,那就按调试的步骤来除错吧
BEIWEIM 2020-09-15
  • 打赏
  • 举报
回复
这个是一个自定义的函数,一运行就出问题
  • 打赏
  • 举报
回复
注释还是有的,只是不是完整程序,谁能知道有什么问题?
BEIWEIM 2020-09-09
  • 打赏
  • 举报
回复
好的谢谢提醒
青蛙工作室 2020-09-09
  • 打赏
  • 举报
回复
1,读别人的代码是非常苦逼的事,何况这么长的代码,谁会花时间去读完? 2,一长串代码没有一句注释,难道要去吃透这么长的东西?脑子和时间都是很宝贵的 3,完全没有说明,没有表达你的想要的目的,也没有标明哪句出错,无从帮起 4,新注册号,0结贴率 楼主知道为什么没人回复了吗?换位思考一下,也许你会知道应该怎么写一个求助贴。

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧