按照:https://blog.csdn.net/aoamca84802/article/details/101811895的思路
取中值时半径为三,改进后比一般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<
现在每次最多需要比较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(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(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<