#ifndef _TOOLS_H_
#define _TOOLS_H_
#ifdef __cplusplus
extern "C"
{
#endif
int uCharDataToFloatData(unsigned char * inData, float * outData, int width, int height, int channels);
/*
*flag = 0 是对于多通道时使用,这时在全部通道中找最大值和最小值
*flag = 1 在每个通道中分别找最大值和最小值
*/
int floatDataToUCharData(float * inData, unsigned char * outData, int width, int height, int channels, int flag);
#ifdef __cplusplus
}
#endif
#endif
Tools.c
#include
#include
#include "Tools.h"
int uCharDataToFloatData(unsigned char * inData, float * outData, int width, int height, int channels){
int i, j, z;
int temp;
if(channels > 32){
printf("channels number is large.\n");
return -1;
}
for(i = 0; i < height; i ++){
for(j = 0; j < width; j ++){
for(z = 0; z < channels; z ++){
temp = (int)inData[(i * width + j) * channels + z];
outData[(i * width + j) * channels + z] = (float)temp;
}
}
}
return 0;
}
/*
*flag = 0 是对于多通道时使用,这时在全部通道中找最大值和最小值
*flag = 1 在每个通道中分别找最大值和最小值
*/
int floatDataToUCharData(float * inData, unsigned char * outData, int width, int height, int channels, int flag){
int i, j, z;
int temp;
float maxNumber[32] = {-10000.0f};
float minNumber[32] = {10000.0f};
if(channels > 32){
printf("channels number is large.\n");
return -1;
}
if(flag == 1){
for(z = 0; z < channels; z ++){
for(i = 0; i < height; i ++){
for(j = 0; j < width; j ++){
if(inData[(i * width + j) * channels + z] > maxNumber[z]){
maxNumber[z] = inData[(i * width + j) * channels + z];
}
if(inData[(i * width + j) * channels + z] < minNumber[z]){
minNumber[z] = inData[(i * width + j) * channels + z];
}
}
}
}
for(i = 0; i < height; i ++){
for(j = 0; j < width; j ++){
for(z = 0; z < channels; z ++){
temp = (int)(255.0f * (inData[(i * width + j) * channels + z] - minNumber[z]) / (maxNumber[z] - minNumber[z]));
outData[(i * width + j) * channels + z] = (unsigned char)temp;
}
}
}
}else if(flag == 0){
for(z = 0; z < channels; z ++){
for(i = 0; i < height; i ++){
for(j = 0; j < width; j ++){
if(inData[(i * width + j) * channels + z] > maxNumber[0]){
maxNumber[0] = inData[(i * width + j) * channels + z];
}
if(inData[(i * width + j) * channels + z] < minNumber[0]){
minNumber[0] = inData[(i * width + j) * channels + z];
}
}
}
}
for(i = 0; i < height; i ++){
for(j = 0; j < width; j ++){
for(z = 0; z < channels; z ++){
temp = (int)(255.0f * (inData[(i * width + j) * channels + z] - minNumber[0]) / (maxNumber[0] - minNumber[0]));
outData[(i * width + j) * channels + z] = (unsigned char)temp;
}
}
}
}
return 0;
}
BoxFilter.h BoxFilter.c是均值滤波和方框滤波的头文件、核心函数
BoxFilter.h
#ifndef _BOXFILTER_H_
#define _BOXFILTER_H_
#ifdef __cplusplus
extern "C"
{
#endif
/*
*inData 输入数据
*outData 输出数据
*width 输入数据的宽
*height 输入数据的高
*channels 维度
*flag flag = 0均值滤波 flag = 1方框滤波
*/
int boxFilter(float * inData, float * outData, int width, int height, int boxWidth, int boxHeight, int channels, int flag);
#ifdef __cplusplus
}
#endif
#endif
BoxFilter.c
#include
#include
#include
#include "BoxFilter.h"
/*
*inData 输入数据
*outData 输出数据
*width 输入数据的宽
*height 输入数据的高
*channels 维度
*flag flag = 0均值滤波 flag = 1方框滤波
*/
int boxFilter(float * inData, float * outData, int width, int height, int boxWidth, int boxHeight, int channels, int flag){
int boxWidthTemp, boxHeightTemp;
int i, j, z;
int m, n;
int count = 0;
float sumNumber = 0.0f;
if(channels > 32){
printf("channels number is large.\n");
return -1;
}
if(boxWidth % 2 == 0){
boxWidthTemp = boxWidth / 2 - 1;
}else{
boxWidthTemp = boxWidth / 2;
}
if(boxHeight % 2 == 0){
boxHeightTemp = boxHeight / 2 - 1;
}else{
boxHeightTemp = boxHeight / 2;
}
for(z = 0; z < channels; z ++){
for(i = 0; i < height; i ++){
for(j = 0; j < width; j ++){
if(flag == 0){
count = 0;
}else if(flag == 1){
count = 1;
}
sumNumber = 0.0f;
for(m = -boxHeightTemp; m < boxHeight - boxHeightTemp; m ++){
for(n = -boxWidthTemp; n < boxWidth - boxWidthTemp; n ++){
if(i + m >= 0 && j + n >= 0 && i + m < height && j + n < width){
sumNumber += inData[((i + m) * width + (j + n)) * channels + z];
if(flag == 0){
count ++;
}
}
}
}
outData[(i * width + j) * channels + z] = sumNumber / (float)count;
}
}
}
return 0;
}
主函数调用程序
#include "BoxFilter.h"
#include "Tools.h"
#include
using namespace cv;
int main()
{
int imageWidth, imageHeight;
int channels = 1;
//使用opencv读取一张图片
//D:\\workSpace\\VSWorkSpace\\ImageProcess\\ImageProcess\\viewImage.jpg为图片的路径
//1代表3通道彩色图,0代表1通道灰度图
Mat mImage = imread("D:\\workSpace\\VSWorkSpace\\ImageProcess\\ImageProcess\\viewImage.jpg", 1);
imshow("srcImage", mImage);
float * imageData = NULL;
float * imageOutData = NULL;
imageWidth = mImage.cols;
imageHeight = mImage.rows;
channels = mImage.channels();
imageData = (float*)malloc(sizeof(float) * imageWidth * imageHeight * channels);
imageOutData = (float*)malloc(sizeof(float) * imageWidth * imageHeight * channels);
//图像数据格式转换,unsigned char 转换为 float 型数据
uCharDataToFloatData(mImage.data, imageData, imageWidth, imageHeight, channels);
//实现均值滤波和方框滤波
boxFilter(imageData, imageOutData, imageWidth, imageHeight, 5, 5, channels, 0);
//图像数据格式转化,float 转化为 unsigned char 型数据
floatDataToUCharData(imageOutData, mImage.data, imageWidth, imageHeight, channels, 1);
//显示处理后的图像
imshow("boxFilterImage", mImage);
waitKey(0);
free(imageData);
free(imageOutData);
return 0;
}
**************************3通道彩色图的原始图像**********************
*************************3通道彩色图处理后图像***************************
**************************1通道灰度图的原始图像**********************
*************************1通道灰度图处理后图像***************************