影象的均值濾波和方框濾波
阿新 • • 發佈:2019-01-04
- 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通道彩色圖處理後圖像***************************
**************************1通道灰度圖的原始影象**********************
*************************1通道灰度圖處理後圖像***************************