图像的均值滤波和方框滤波

  1. Tools.h Tools.c包含对图像数据格式的转换的函数,unsigned char 型数据转换为float型数据。
    Tools.h
#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通道彩色图的原始图像**********************
图像的均值滤波和方框滤波_第1张图片
*************************3通道彩色图处理后图像***************************
图像的均值滤波和方框滤波_第2张图片
**************************1通道灰度图的原始图像**********************
图像的均值滤波和方框滤波_第3张图片
*************************1通道灰度图处理后图像***************************
图像的均值滤波和方框滤波_第4张图片

你可能感兴趣的:(图像处理)