OpenCV中的熵滤波器类似于matlab中的entropyfilter()函数
Entropy Filter in OpenCV similar to entropyfilt() function in matlab
我正在opencv 3中寻找entropyfilt()函数,所以我很感激能找到这篇文章:在opencv 中查找熵
我正在尝试Umka的优化代码,但我得到的唯一结果是一个完全白色的图像。我在代码中唯一更改的是sub_to_ind函数中的数据类型,编译器无法识别int32_t,并且该函数是用int值调用的,所以我认为这不是问题。
原件:
静态int32_t sub_to_id(int32_t*coords,int32_t*cumprod,int32_t num_dims)
更改:
静态int sub_to_id(int*coords,int*cumprod,int num_dims)
这是我的完整代码:
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <time.h>
static int sub_to_ind(int *coords, int *cumprod, int num_dims)
{
int index = 0;
int k;
assert(coords != NULL);
assert(cumprod != NULL);
assert(num_dims > 0);
for (k = 0; k < num_dims; k++)
{
index += coords[k] * cumprod[k];
}
return index;
}
static void ind_to_sub(int p, int num_dims, const int size[],
int *cumprod, int *coords)
{
int j;
assert(num_dims > 0);
assert(coords != NULL);
assert(cumprod != NULL);
for (j = num_dims - 1; j >= 0; j--)
{
coords[j] = p / cumprod[j];
p = p % cumprod[j];
}
}
void getLocalEntropyImage(cv::Mat &gray, cv::Rect &roi, cv::Mat &entropy)
{
using namespace cv;
clock_t func_begin, func_end;
func_begin = clock();
//1.define nerghbood model,here it's 9*9
int neighbood_dim = 2;
int neighbood_size[] = {9, 9};
//2.Pad gray_src
Mat gray_src_mat(gray);
Mat pad_mat;
int left = (neighbood_size[0] - 1) / 2;
int right = left;
int top = (neighbood_size[1] - 1) / 2;
int bottom = top;
copyMakeBorder(gray_src_mat, pad_mat, top, bottom, left, right, BORDER_REPLICATE, 0);
Mat *pad_src = &pad_mat;
roi = cv::Rect(roi.x + top, roi.y + left, roi.width, roi.height);
//3.initial neighbood object,reference to Matlab build-in neighbood object system
// int element_num = roi_rect.area();
//here,implement a histogram by ourself ,each bin calcalate gray value frequence
int hist_count[256] = {0};
int neighbood_num = 1;
for (int i = 0; i < neighbood_dim; i++)
neighbood_num *= neighbood_size[i];
//neighbood_corrds_array is a neighbors_num-by-neighbood_dim array containing relative offsets
int *neighbood_corrds_array = (int *)malloc(sizeof(int)*neighbood_num * neighbood_dim);
//Contains the cumulative product of the image_size array;used in the sub_to_ind and ind_to_sub calculations.
int *cumprod = (int *)malloc(neighbood_dim * sizeof(*cumprod));
cumprod[0] = 1;
for (int i = 1; i < neighbood_dim; i++)
cumprod[i] = cumprod[i - 1] * neighbood_size[i - 1];
int *image_cumprod = (int*)malloc(2 * sizeof(*image_cumprod));
image_cumprod[0] = 1;
image_cumprod[1] = pad_src->cols;
//initialize neighbood_corrds_array
int p;
int q;
int *coords;
for (p = 0; p < neighbood_num; p++){
coords = neighbood_corrds_array + p * neighbood_dim;
ind_to_sub(p, neighbood_dim, neighbood_size, cumprod, coords);
for (q = 0; q < neighbood_dim; q++)
coords[q] -= (neighbood_size[q] - 1) / 2;
}
//initlalize neighbood_offset in use of neighbood_corrds_array
int *neighbood_offset = (int *)malloc(sizeof(int) * neighbood_num);
int *elem;
for (int i = 0; i < neighbood_num; i++){
elem = neighbood_corrds_array + i * neighbood_dim;
neighbood_offset[i] = sub_to_ind(elem, image_cumprod, 2);
}
//4.calculate entropy for pixel
uchar *array = (uchar *)pad_src->data;
//here,use entroy_table to avoid frequency log function which cost losts of time
float entroy_table[82];
const float log2 = log(2.0f);
entroy_table[0] = 0.0;
float frequency = 0;
for (int i = 1; i < 82; i++){
frequency = (float)i / 81;
entroy_table[i] = frequency * (log(frequency) / log2);
}
int neighbood_index;
// int max_index=pad_src->cols*pad_src->rows;
float e;
int current_index = 0;
int current_index_in_origin = 0;
for (int y = roi.y; y < roi.height; y++){
current_index = y * pad_src->cols;
current_index_in_origin = (y - 4) * gray.cols;
for (int x = roi.x; x < roi.width; x++, current_index++, current_index_in_origin++) {
for (int j = 0; j<neighbood_num; j++) {
neighbood_index = current_index + neighbood_offset[j];
hist_count[array[neighbood_index]]++;
}
//get entropy
e = 0;
for (int k = 0; k < 256; k++){
if (hist_count[k] != 0){
// int frequency=hist_count[k];
e -= entroy_table[hist_count[k]];
hist_count[k] = 0;
}
}
((float *)entropy.data)[current_index_in_origin] = e;
}
}
free(neighbood_offset);
free(image_cumprod);
free(cumprod);
free(neighbood_corrds_array);
func_end = clock();
double func_time = (double)(func_end - func_begin) / CLOCKS_PER_SEC;
std::cout << "func time" << func_time << std::endl;
}
int main(int argc, char** argv)
{
cv::Mat src;
/// Load image
src = cv::imread(argv[1], 1);
if (!src.data)
{
std::cout << "Usage: EntropyFilter <path_to_image>" << std::endl;
return -1;
}
/// Convert to grayscale
cvtColor(src, src, cv::COLOR_BGR2GRAY);
//Calculate Entropy Filter
cv::Rect roi(0, 0, src.cols, src.rows);
cv::Mat dst(src.rows, src.cols, CV_32F);
getLocalEntropyImage(src, roi, dst);
cv::normalize(dst, dst, 0, 255, cv::NORM_MINMAX);
cv::Mat entropy;
dst.convertTo(entropy, CV_8U);
/// Display results
cv::namedWindow("Original", cv::WINDOW_AUTOSIZE);
cv::namedWindow("Entropy Filter", cv::WINDOW_AUTOSIZE);
cv::namedWindow("Entropy Filter2", cv::WINDOW_AUTOSIZE);
cv::imshow("Original", src);
cv::imshow("Entropy Filter", dst);
cv::imshow("Entropy Filter2", entropy);
/// Wait until user exits the program
cv::waitKey(0);
return 0;
}
我做错了什么吗?或者我应该为我使用的每个图像调整任何参数吗?(附言:作为比较示例,我在这篇文章中使用了带有字段的图像:https://dsp.stackexchange.com/questions/15221/entropy-frequency-of-a-natural-image)
感谢
我是Opencv和C++的新手,也面临着同样的问题。事实证明,你不必对输出图像进行归一化,也不必对其进行隐藏。因此,你可以简单地进行
...
getLocalEntropyImage(src, roi, dst);
//dst is your entropy image
/// Display results
cv::namedWindow("Original", cv::WINDOW_AUTOSIZE);
cv::namedWindow("Entropy Filter", cv::WINDOW_AUTOSIZE);
cv::imshow("Original", src);
cv::imshow("Entropy Filter", dst);
/// Wait until user exits the program
cv::waitKey(0);
return 0;
LMS。
谢谢你的伟大作品。
我有你代码的镜像Openframework版本。https://github.com/bemoregt/gromitLocalEntropyFilter.git
我提到了这个线程的链接。
这样可以吗?
最佳,@bemoregt。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- .cpp和.h文件中的模板专用化声明
- 反向给定链表中的K节点
- 正在查找文档以获得PS4平台的C++中的设备信息
- enum是C++中的宏变量还是整数变量
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 将字符串存储在c++中的稳定内存中
- 文本文件中的单词链表
- 递归函数计算序列中的平方和(并输出过程)
- 如何从C++中的依赖类型中获得它所依赖的类型
- C++中的"inline"关键字
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 用C++中的一个变量定义一个常量
- vector.resize()中的分配错误
- 使用指针从C++中的数组中获取最大值
- arr[-1]在c++中的奇怪行为
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 将值指定给向量(2D)的向量中的某个位置
- OpenCV中的熵滤波器类似于matlab中的entropyfilter()函数