中值滤波改进

按照:中值滤波的改进算法 - 游戏者 - 博客园的思路

取中值时半径为三,改进后比一般bfptr算法快20倍以上

以下代码模拟3e7次运算并输出时间,时间在400ms内

#include "bits/stdc++.h"
using namespace std;
#define num_type int
num_type a[9],Max1, Max2, Max3, Med1, Med2, Med3, Min1, Min2, Min3, Min_of_Max, Med_of_Med, Max_of_Min, Med_of_nine;

int find_Max(num_type Max1,num_type Max2,num_type Max3)
{
    if (Max1 <= Max2) {
        if (Max3 <= Max1)return Max3;
        else return  Max1;
    } else {
        if (Max3 <= Max2)return Max3;
        else return Max2;
    }
}
int find_Min(num_type Min1,num_type Min2,num_type Min3)
{
    if (Min1 >= Min2) {
        if (Min3 >= Min1)return  Min3;
        else return  Min1;
    } else {
        if (Min3 >= Min2)return  Min3;
        else return  Min2;
    }
}
int find_Med(num_type Med1,num_type Med2,num_type Med3)
{
    if(Med1>=Med2)
    {
        if(Med3>=Med1)return Med1;
        else if(Med3>=Med2)return Med3;
        else return Med2;
    } else{
        if(Med3>=Med2)return Med2;
        else if(Med3>=Med1)return Med3;
        else return Med1;
    }
}
void three_sort(num_type a,num_type b,num_type c,num_type *Max,num_type *Med,num_type *Min)
{
    if(a>b)
    {
        if(c>a)*Max=c,*Med=a,*Min=b;
        else if(c>b)*Max=a,*Med=c,*Min=b;
        else *Max=a,*Med=b,*Min=c;
    }
    else
        if(c>b)*Max=c,*Med=b,*Min=a;
        else if(c>a)*Max=b,*Med=c,*Min=a;
        else *Max=b,*Med=a,*Min=c;
}
int main() {

    srand((int)time(0));
    double begin,end;
    while(1){
        for (int i = 0; i < 9; i++)
            a[i] =rand()%100;
        begin = clock();

        for (int j = 0; j < 3e7; j++) {
            three_sort(a[0],a[1],a[2],&Max1,&Med1,&Min1);
            three_sort(a[3],a[4],a[5],&Max2,&Med2,&Min2);
            three_sort(a[6],a[7],a[8],&Max3,&Med3,&Min3);
           if (Max1 <= Max2) {
                if (Max3 <= Max1)Min_of_Max = Max3;
                else Min_of_Max = Max1;
            } else {
                if (Max3 <= Max2)Min_of_Max = Max3;
                else Min_of_Max = Max2;
            }
          // Min_of_Max= find_Max(Max1,Max2,Max3);
          if(Med1>=Med2)
          {
              if(Med3>=Med1)Med_of_Med=Med1;
              else if(Med3>=Med2)Med_of_Med=Med3;
              else Med_of_Med=Med2;
          } else{
              if(Med3>Med2)Med_of_Med=Med2;
              else if(Med3>=Med1)Med_of_Med=Med3;
              else Med_of_Med=Med1;
          }
      //  Med_of_Med= find_Med(Med1,Med2,Med3);

            if (Min1 >= Min2) {
                if (Min3 >= Min1)Max_of_Min = Min3;
                else Max_of_Min = Min1;
            } else {
                if (Min3 >= Min2)Max_of_Min = Min3;
                else Max_of_Min = Min2;
            }
            //Max_of_Min=find_Min(Min1,Min2,Min3);
          if(Min_of_Max>=Med_of_Med)
          {
              if(Max_of_Min>=Min_of_Max)Med_of_nine=Min_of_Max;
              else if(Max_of_Min>=Med_of_Med)Med_of_nine=Max_of_Min;
              else Med_of_nine=Med_of_Med;
          } else{
              if(Max_of_Min>Med_of_Med)Med_of_nine=Med_of_Med;
              else if(Max_of_Min>=Min_of_Max)Med_of_nine=Max_of_Min;
              else Med_of_nine=Min_of_Max;
          }
        //  Med_of_nine= find_Med(Min_of_Max,Med_of_Med,Max_of_Min);

        }
         end = clock();
        sort(a,a+9);
        cout<<Med_of_nine<<" "<<a[4]<<endl;
        cout << (end - begin) / 1000000 << endl;
    }
    return 0;
}

再改进:

现在每次最多需要比较17次才能求出中值,但

指针每次偏移,意味着一行或是一列更新,剩余两行、两列不变,那么每次更新可以节省6次比较,理论上可在150ms内完成3e7次计算

代码:

#include "bits/stdc++.h"
#include "ctmf.h"
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;
#define num_type unsigned char
#define    scale  0.1
#define width 128
#define high 72


void v_to_mat(Mat &image1, num_type b[][width]) {
    for (int i = 0; i < high; i++) {
        for (int j = 0; j < width; j++) {
            image1.at<uchar>(i, j) = b[i][j];
        }
    }
}
void mat_to_v(Mat &image1, num_type b[][width]) {
    for (int i = 0; i < high; i++) {
        for (int j = 0; j < width; j++) {
            b[i][j] = image1.at<uchar>(i, j);
        }
    }
}


void Binarization(num_type input[][width], num_type output[][width], num_type val) {
    for (int i = 0; i < high; i++) {
        for (int j = 0; j < width; j++) {
            output[i][j] = input[i][j] >= val ? 255 : 0;
        }
    }
}

void three_sort(num_type a, num_type b, num_type c, num_type *Max, num_type *Med, num_type *Min) {
    if (a >= b) {
        if (c >= a)*Max = c, *Med = a, *Min = b;
        else if (c >= b)*Max = a, *Med = c, *Min = b;
        else *Max = a, *Med = b, *Min = c;
    } else if (c >= b)*Max = c, *Med = b, *Min = a;
    else if (c >= a)*Max = b, *Med = c, *Min = a;
    else *Max = b, *Med = a,* Min = c;
}

void median_filtering(num_type img[][width]) {
    num_type Max1, Max2, Max3, Med1, Med2, Med3, Min1, Min2, Min3, Min_of_Max, Med_of_Med, Max_of_Min;
    int i, j;
    for (i = high-2; i ; i--) {
        three_sort(img[i - 1][0], img[i][0], img[i + 1][0], &Max1, &Med1, &Min1);
        three_sort(img[i - 1][1], img[i][1], img[i + 1][1], &Max2, &Med2, &Min2);
        three_sort(img[i - 1][2], img[i][2], img[i + 1][2], &Max3, &Med3, &Min3);
        if (Max1 <= Max2) {
            if (Max3 <= Max1)Min_of_Max = Max3;
            else Min_of_Max = Max1;
        } else {
            if (Max3 <= Max2)Min_of_Max = Max3;
            else Min_of_Max = Max2;
        }
        if (Med1 >= Med2) {
            if (Med3 >= Med1)Med_of_Med = Med1;
            else if (Med3 >= Med2)Med_of_Med = Med3;
            else Med_of_Med = Med2;
        } else {
            if (Med3 > Med2)Med_of_Med = Med2;
            else if (Med3 >= Med1)Med_of_Med = Med3;
            else Med_of_Med = Med1;
        }
        if (Min1 >= Min2) {
            if (Min3 >= Min1)Max_of_Min = Min3;
            else Max_of_Min = Min1;
        } else {
            if (Min3 >= Min2)Max_of_Min = Min3;
            else Max_of_Min = Min2;
        }
        if (Min_of_Max >= Med_of_Med) {
            if (Max_of_Min >= Min_of_Max)img[i][1] = Min_of_Max;
            else if (Max_of_Min >= Med_of_Med)img[i][1] = Max_of_Min;
            else img[i][1] = Med_of_Med;
        } else {
            if (Max_of_Min > Med_of_Med)img[i][1] = Med_of_Med;
            else if (Max_of_Min >= Min_of_Max)img[i][1] = Max_of_Min;
            else img[i][1] = Min_of_Max;
        }
        for (j = 2; j < width - 1; j++) {
            Max1=Max2,Med1=Med2,Min1=Min2;
            Max2=Max3,Med2=Med3,Min2=Min3;
            three_sort(img[i - 1][j + 1], img[i][j + 1], img[i + 1][j + 1], &Max3, &Med3, &Min3);
            if (Max1 <= Max2) {
                if (Max3 <= Max1)Min_of_Max = Max3;
                else Min_of_Max = Max1;
            } else {
                if (Max3 <= Max2)Min_of_Max = Max3;
                else Min_of_Max = Max2;
            }
            if (Med1 >= Med2) {
                if (Med3 >= Med1)Med_of_Med = Med1;
                else if (Med3 >= Med2)Med_of_Med = Med3;
                else Med_of_Med = Med2;
            } else {
                if (Med3 > Med2)Med_of_Med = Med2;
                else if (Med3 >= Med1)Med_of_Med = Med3;
                else Med_of_Med = Med1;
            }

            if (Min1 >= Min2) {
                if (Min3 >= Min1)Max_of_Min = Min3;
                else Max_of_Min = Min1;
            } else {
                if (Min3 >= Min2)Max_of_Min = Min3;
                else Max_of_Min = Min2;
            }
            if (Min_of_Max >= Med_of_Med) {
                if (Max_of_Min >= Min_of_Max)img[i][j] = Min_of_Max;
                else if (Max_of_Min >= Med_of_Med)img[i][j] = Max_of_Min;
                else img[i][j] = Med_of_Med;
            } else {
                if (Max_of_Min > Med_of_Med)img[i][j] = Med_of_Med;
                else if (Max_of_Min >= Min_of_Max)img[i][j] = Max_of_Min;
                else img[i][j] = Min_of_Max;
            }
        }
    }

}


int main() {

    srand((int) time(0));
    Mat image,cc;
    double begin, end;
    int val = 180;
    image = imread("/home/rubo/2.png");
    Size dsize = Size(image.cols*scale, image.rows*scale);
    Mat img2 = Mat(dsize, CV_32S);
    resize(image, image, dsize);
    if (image.empty()) {
        cout << "no picture!" << endl;
        return 0;
    }
    num_type img[high][width];
num_type img1[high][width];
    cvtColor(image, image, COLOR_RGB2GRAY, 0);
    Mat image1;
    image.copyTo(cc);
    mat_to_v(image, img);
    begin=clock();
for(int i=0;i<1000;i++)
         median_filtering(img);
    end=clock();
    cout<<(end-begin)/1000000<<endl;
   v_to_mat(cc,img);
    begin = clock();
    medianBlur(image, image1, 3);//输入,输出,7通道
    end = clock();
    cout << (end - begin) / 1000000 << endl;
    inRange(image, 0, val, image);
    imshow("im", image);
    inRange(image1, 0, val, image1);
    imshow("im1", image1);
    inRange(cc, 0, val, cc);
    imshow("bb",cc);
    waitKey(0);
    return 0;
}

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoseHu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值