1. 程式人生 > >影象的均值濾波和方框濾波

影象的均值濾波和方框濾波

  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 <stdio.h>
#include <stdlib.h>
#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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#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 <opencv2\opencv.hpp>
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通道彩色圖的原始影象
*************************3通道彩色圖處理後圖像***************************
這裡寫圖片描述
**************************1通道灰度圖的原始影象**********************
這裡寫圖片描述
*************************1通道灰度圖處理後圖像***************************
這裡寫圖片描述