Пример #1
0
/*
 * 45°回転したIntegral Image
 */
void 
nv_integral_tilted(nv_matrix_t *integral,
				   const nv_matrix_t *img, int channel)
{
	int row, col, scol, srow;
	int erow = img->rows + 1;
	int ecol = img->cols + 1;
	nv_matrix_t *prev_tilted = nv_matrix_alloc(img->cols + 1, 1);

	NV_ASSERT(
		integral->rows - 1 == img->rows 
		&& integral->cols - 1 == img->cols
	);

	nv_matrix_zero(prev_tilted);
	nv_matrix_zero(integral);

	for (scol = img->cols; scol > 0; --scol) {
		float tilted_sum = 0.0f;
		for (row = 1, col = scol; row < erow && col < ecol; ++row, ++col) {
			float tilted_val = NV_MAT3D_V(img, row - 1, col - 1, channel);
			if (col + 1 == ecol) {
				NV_MAT3D_V(integral, row, col, 0) = 
					NV_MAT3D_V(integral, row - 1, col, 0)
					+ tilted_sum + tilted_val;
			} else {
				NV_MAT3D_V(integral, row, col, 0) = 
					NV_MAT3D_V(integral, row - 1, col + 1, 0) 
					+ NV_MAT_V(prev_tilted, 0, col)
					+ tilted_sum + tilted_val;
			}
			tilted_sum += tilted_val;
			NV_MAT_V(prev_tilted, 0, col) = tilted_sum;
		}
	}
	for (srow = 2; srow < erow; ++srow) {
		float tilted_sum = 0.0f;
		for (row = srow, col = 1; row < erow && col < ecol; ++row, ++col) {
			float tilted_val = NV_MAT3D_V(img, row - 1, col - 1, channel);
			if (col + 1 == ecol) {
				NV_MAT3D_V(integral, row, col, 0) = 
					NV_MAT3D_V(integral, row - 1, col, 0)
					+ tilted_sum + tilted_val;
			} else {
				NV_MAT3D_V(integral, row, col, 0) = 
					NV_MAT3D_V(integral, row - 1, col + 1, 0) 
					+ NV_MAT_V(prev_tilted, 0, col)
					+ tilted_sum + tilted_val;
			}
			tilted_sum += tilted_val;
			NV_MAT_V(prev_tilted, 0, col) = tilted_sum;
		}
	}

	nv_matrix_free(&prev_tilted);
}
Пример #2
0
/*
 * Integral Image
 * 積分画像
 */
void 
nv_integral(nv_matrix_t *integral,
			const nv_matrix_t *img, int channel)
{
	int row, col;
	int erow = img->rows + 1;
	int ecol = img->cols + 1;

	NV_ASSERT(
		integral->rows - 1 == img->rows 
		&& integral->cols - 1 == img->cols
	);

	nv_matrix_zero(integral);
	for (row = 1; row < erow; ++row) {
		float col_sum = 0.0f;
		for (col = 1; col < ecol; ++col) {
			float col_val = NV_MAT3D_V(img, row - 1, col - 1, channel);
			NV_MAT3D_V(integral, row, col, 0) =	
				NV_MAT3D_V(integral, row - 1, col, 0) + col_sum + col_val;
			col_sum += col_val;
		}
	}
}
Пример #3
0
void 
nv_pstable_hash(const nv_pstable_t *ps, nv_pstable_hash_t *hash, const nv_matrix_t *vec, int vec_m)
{
	int k, l;
	float r_fac = 1.0f / ps->r;

	NV_ASSERT(ps->a->n == vec->n);

	memset(hash, 0, sizeof(nv_pstable_hash_t) * ps->l);

	for (l = 0; l < ps->l; ++l) {
		for (k = 0; k < ps->k; ++k) {
			/* s = (ax + b) / r */
			float s = nv_vector_dot(ps->a, NV_MAT_M(ps->a, l, k), vec, vec_m);
			s += NV_MAT3D_V(ps->b, l, k, 0);
			s *= r_fac;
			hash[l] = hash[l] * 33 + (int)s;
		}
	}
}
Пример #4
0
void
nv_matrix3d_print(FILE *out, const nv_matrix_t *mat, int channel)
{
	int row, col;

	fprintf(out, "(");
	for (row = 0; row < mat->rows; ++row) {
		if (row != 0) {
			fprintf(out, ",\n");
		}
		fprintf(out, "[ ");
		for (col = 0; col < mat->cols; ++col) {
			if (col != 0) {
				fprintf(out, ", ");
			}
			fprintf(out, "%10E", NV_MAT3D_V(mat, row, col, channel));
		}
		fprintf(out, "]");
	}
	fprintf(out, ");\n");
}
Пример #5
0
otama_image_t *
otama_image_load_rgb8(int width, int height, const void *data)
{
	otama_image_t *p = nv_alloc_type(otama_image_t, 1);
	int x, y, c;
	const uint8_t *d = (const uint8_t *)data;

	p->has_id = 0;
	p->image = nv_matrix3d_alloc(3, height, width);
	memset(&p->id, 0, sizeof(otama_id_t)); // TODO: insert
	
	for (y = 0; y < height; ++y) {
		for (x = 0; x < height; ++x) {
			for (c = 0; c < 3; ++c) {
				NV_MAT3D_V(p->image, y, x, 2 - c) = (float)*d++;
			}
		}
	}

	return p;
}
void nv_face_haarlike(nv_face_haarlike_normalize_e normalize_type,
	nv_matrix_t *feature, 
	int feature_m,
	const nv_matrix_t *sum,
	int x, int y, int width, int height)
{
	int ix, iy, n;
	float v, vmax, vmin;
	float xscale = width / 32.0f;
	float yscale = height / 32.0f;
	float ystep = yscale;
	float xstep = xscale;
	int hystep = (32 - 8) / 2 * 8;
	int sy = NV_ROUND_INT(4.0f * ystep);
	int sx = NV_ROUND_INT(4.0f * xstep);
	int hy, hx;

	nv_vector_zero(feature, feature_m);

	// level1
#ifdef _OPENMP
	//#pragma omp parallel for private(ix)
#endif
	for (iy = 0, hy = 0; iy < 32-8; iy += 2, ++hy) {
		int py = y + NV_ROUND_INT(ystep * iy);
		int ey = py + NV_ROUND_INT(8.0f * ystep);
		const float pty = (ey - py) * 255.0f;
		for (ix = 0, hx = 0; ix < 32-8; ix += 2, ++hx) {
			int px = x + NV_ROUND_INT(xstep * ix);
			int ex = px + NV_ROUND_INT(8.0f * xstep);
			float p1, p2, area, ptx;

			// 全エリア
			area = NV_MAT3D_V(sum, ey, ex, 0)
				- NV_MAT3D_V(sum, ey, px, 0)
				- (NV_MAT3D_V(sum, py, ex, 0) - NV_MAT3D_V(sum, py, px, 0));

			// 1
			// [+]
			// [-]
			p1 = NV_MAT3D_V(sum, py + sy, ex, 0)
				- NV_MAT3D_V(sum, py + sy, px, 0)
				- (NV_MAT3D_V(sum, py, ex, 0) - NV_MAT3D_V(sum, py, px, 0));
			p2 = area - p1;
			ptx = (ex - px) * 255.0f;
			p1 /= ((py + sy) - py) * ptx;
			p2 /= (ey - (py + sy)) * ptx;
			if (p1 > p2) {
				NV_MAT_V(feature, feature_m, hy * hystep + hx * 8 + 0) = p1 - p2;
			} else {
				NV_MAT_V(feature, feature_m, hy * hystep + hx * 8 + 1) = p2 - p1;
			}

			// 2
			// [+][-]
			p1 = NV_MAT3D_V(sum, ey, px + sx, 0)
				- NV_MAT3D_V(sum, ey, px, 0)
				- (NV_MAT3D_V(sum, py, px + sx, 0) - NV_MAT3D_V(sum, py, px, 0));
			p2 = area - p1;
			p1 /= ((px + sx) - px) * pty;
			p2 /= (ex - (px + sx)) * pty;
			if (p1 > p2) {
				NV_MAT_V(feature, feature_m, hy * hystep + hx * 8 + 2) = p1 - p2;
			} else {
				NV_MAT_V(feature, feature_m, hy * hystep + hx * 8 + 3) = p2 - p1;
			}

			// 3
			p1 = nv_face_haarlike_diagonal_filter(1, sum, px, py, xscale, yscale);
			if (p1 > 0.0f) {
				NV_MAT_V(feature, feature_m, hy * hystep + hx * 8 + 4) = p1;
			} else {
				NV_MAT_V(feature, feature_m, hy * hystep + hx * 8 + 5) = -p1;
			}

			// 4
			p1 = nv_face_haarlike_diagonal_filter(2, sum, px, py, xscale, yscale);
			if (p1 > 0.0f) {
				NV_MAT_V(feature, feature_m, hy * hystep + hx * 8 + 6) = p1;
			} else {
				NV_MAT_V(feature, feature_m, hy * hystep + hx * 8 + 7) = -p1;
			}
		}
	}

	// 正規化
	switch (normalize_type) {
	case NV_NORMALIZE_MAX:
		// Maximum=1.0
		vmax = 0.0f;
		vmin = FLT_MAX;
		for (n = 0; n < feature->n; ++n) {
			if (NV_MAT_V(feature, feature_m, n) > vmax) {
				vmax = NV_MAT_V(feature, feature_m, n);
			}
			if (NV_MAT_V(feature, feature_m, n) != 0.0f
				&& NV_MAT_V(feature, feature_m, n) < vmin) 
			{
				vmin = NV_MAT_V(feature, feature_m, n);
			}
		}
		if (vmax != 0.0f && vmax > vmin) {
			v = 1.0f / (vmax - vmin);
			for (n = 0; n < feature->n; ++n) {
				if (NV_MAT_V(feature, feature_m, n) != 0.0f) {
					NV_MAT_V(feature, feature_m, n) = (NV_MAT_V(feature, feature_m, n) - vmin) * v;
				}
			}
		}
		break;
	case NV_NORMALIZE_NORM:
		// Vector Norm=1.0
		v = 0.0f;
		for (n = 0; n < feature->n; ++n) {
			v += NV_MAT_V(feature, feature_m, n) * NV_MAT_V(feature, feature_m, n);
		}
		if (v != 0.0) {
			v = 1.0f / sqrtf(v);
			for (n = 0; n < feature->n; ++n) {
				NV_MAT_V(feature, feature_m, n) *= v;
			}
		}
		break;
	case NV_NORMALIZE_NONE:
	default:
		break;
	}
}
Пример #7
0
void nv_shapecontext_feature(nv_shapecontext_t *sctx,
							const nv_matrix_t *img,
							float r
)
{
	int m, row, col, pc, i, l;
	nv_matrix_t *edge = nv_matrix3d_alloc(1, img->rows, img->cols);
	nv_matrix_t *points = nv_matrix_alloc(2, img->m);
	int *rand_idx = (int *)nv_malloc(sizeof(int) * img->m);
	float u_x, u_y, p_x, p_y, r_e;
	int pn;

	// 細線化
	nv_matrix_zero(points);
	nv_shapecontext_edge_image(edge, img);
	pc = 0;
	u_x = 0.0f;
	u_y = 0.0f;
	for (row = 0; row < edge->rows; ++row) {
		for (col = 0; col < edge->cols; ++col) {
			if (NV_MAT3D_V(edge, row, col, 0) > 50.0f) {
				NV_MAT_V(points, pc, 0) = (float)row;
				NV_MAT_V(points, pc, 1) = (float)col;
				++pc;
				u_y += (float)row;
				u_x += (float)col;
			}
		}
	}
	u_x /= pc;
	u_y /= pc;
	// 指定数の特徴にする(ランダム)
	pn = NV_MIN(pc, sctx->sctx->list);
	nv_shuffle_index(rand_idx, 0, pc);
#if 1
	{
		float max_x, max_y;

		if (pc < sctx->sctx->list) {
			// 足りないときはランダムに増やす
			for (i = pc; i < sctx->sctx->list; ++i) {
				rand_idx[i] = (int)(nv_rand() * pn);
			}
		}
		pc = pn = sctx->sctx->list;

		// 半径を求める

		max_x = 0.0f;
		max_y = 0.0f;
		for (m = 0; m < pn; ++m) {
			float yd = fabsf(NV_MAT_V(points, rand_idx[m], 0) - u_y);
			float xd = fabsf(NV_MAT_V(points, rand_idx[m], 1) - u_x);
			max_x = NV_MAX(max_x, xd);
			max_y = NV_MAX(max_y, yd);
		}
		r = (float)img->rows/2.0f;//NV_MAX(max_x, max_y) * 1.0f;
	}
#endif

	// log(r) = 5の基底定数を求める
	r_e = powf(r, 1.0f / NV_SC_LOG_R_BIN);

	// histgramを計算する
	sctx->n = pn;
	nv_matrix_zero(sctx->sctx);
	nv_matrix_zero(sctx->tan_angle);

	for (l = 0; l < pn; ++l) {
		// tangent angle
#if 0
		float max_bin = 0.0f, min_bin = FLT_MAX;
		float tan_angle = tangent_angle(
			r,
			NV_MAT_V(points, rand_idx[l], 0),
			NV_MAT_V(points, rand_idx[l], 1),
			points, pc);
#else
		float tan_angle = 0.0f;
#endif
		p_y = NV_MAT_V(points, rand_idx[l], 0);
		p_x = NV_MAT_V(points, rand_idx[l], 1);
		NV_MAT_V(sctx->tan_angle, l, 0) = tan_angle;
		NV_MAT_V(sctx->coodinate, l, 0) = p_y;
		NV_MAT_V(sctx->coodinate, l, 1) = p_x;
		NV_MAT_V(sctx->radius, l, 0) = r;

		// shape context
		for (i = 0; i < pn; ++i) {
			// # i ≠ l判定はとりあえずしない
			float xd = NV_MAT_V(points, rand_idx[i], 1) - p_x;
			float yd = NV_MAT_V(points, rand_idx[i], 0) - p_y;
			//int row = i / img->rows;
			//int col = i % img->rows;
			//float xd = col - p_x;
			//float yd = row - p_y;
			float theta;
			float log_r = logf(sqrtf(xd * xd + yd * yd)) / logf(r_e);
			float atan_r = atan2f(xd, yd);

			//if (NV_MAT3D_V(img, row, col, 0) == 0.0f) {
			//	continue;
			//}
			if (i == l) {
				continue;
			}

			if (atan_r < 0.0f) {
				atan_r = 2.0f * NV_PI + atan_r;
			}
			if (tan_angle > 0.0f) {
				if (atan_r + tan_angle > 2.0f * NV_PI) {
					atan_r = atan_r + tan_angle - 2.0f * NV_PI;
				} else {
					atan_r += tan_angle;
				}
			} else {
				if (atan_r + tan_angle < 0.0f) {
					atan_r = 2.0f * NV_PI + (atan_r + tan_angle);
				} else {
					atan_r += tan_angle;
				}
			}

			theta = atan_r / (2.0f * NV_PI / NV_SC_THETA_BIN);
			if (theta < NV_SC_THETA_BIN && log_r < NV_SC_LOG_R_BIN) {
				NV_MAT3D_LIST_V(sctx->sctx, l, (int)log_r, (int)theta, 0) += 1.0f;
			}
		}
#if 0
		for (row = 0; row < NV_SC_LOG_R_BIN; ++row) {
			for (col = 0; col < NV_SC_THETA_BIN; ++col) {
				max_bin = NV_MAX(max_bin, NV_MAT3D_LIST_V(sctx->sctx, l, row, col, 0));
				min_bin = NV_MIN(min_bin, NV_MAT3D_LIST_V(sctx->sctx, l, row, col, 0));
			}
		}
		if (max_bin > 0.0f) {
			for (row = 0; row < NV_SC_LOG_R_BIN; ++row) {
				for (col = 0; col < NV_SC_THETA_BIN; ++col) {
					NV_MAT3D_LIST_V(sctx->sctx, l, row, col, 0) 
						= (NV_MAT3D_LIST_V(sctx->sctx, l, row, col, 0) - min_bin) / (max_bin - min_bin);
				}
			}
		}
#endif
	}
	nv_matrix_free(&edge);
	nv_matrix_free(&points);
	nv_free(rand_idx);
}