#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <iostream>
using namespace cv;
using namespace std;
/** @function main */
int main(int argc, char** argv)
{
Mat src, src_gray;
Mat grad;
char* window_name = "Sobel Demo - Simple Edge Detector";
int scale = 1;
int delta = 0;
int sum1 = 0;
int ddepth = CV_16S;
int c;
/// 装载图像
src = imread(argv[1]);
if (!src.data)
{
return -1;
}
const int width = src.cols;
const int height = src.rows;
GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);
Mat binary_img(height,width,CV_8UC1);
/// 转换为灰度图
cvtColor(src, src_gray, CV_RGB2GRAY);
/// 创建显示窗口
namedWindow(window_name, CV_WINDOW_AUTOSIZE);
/// 创建 grad_x 和 grad_y 矩阵
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;
/// 求 X方向梯度
//Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
Sobel(src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
char name[100];
Mat save_grad;
convertScaleAbs(grad_x, abs_grad_x);
sprintf(name, "E:/02.jpg");
imwrite(name, abs_grad_x);
imshow("【效果图】 X方向Sobel", abs_grad_x);
/// 求Y方向梯度
//Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
Sobel(src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_y, abs_grad_y);
imshow("【效果图】Y方向Sobel", abs_grad_y);
/// 合并梯度(近似)
/*addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
imshow(window_name, grad);*/
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
unsigned char pixel_value = abs_grad_x.at<uchar>(i, j);
size_t square_value = pixel_value*pixel_value;
sum1 += square_value;
}
}
double threshold_x = (4 * sum1) / (width*height);
int count = 0;
std::vector<int> statistic;
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++)
{
unsigned char pixel_value = abs_grad_x.at<uchar>(i, j);
size_t square_value = pixel_value*pixel_value;
//if (pixel_value > 90)
// int k=pixel_value;
if (square_value>threshold_x)
{
binary_img.at<uchar>(i, j) = 255;
}
else{
binary_img.at<uchar>(i, j) = 0;
}
}
}
int location = 0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
unsigned char binary_value = binary_img.at<uchar>(i, j);
if (binary_value == 255)
{
++count;
if (count == 1)
{
location = j;
}
if ((j - location) == (count-1))
{
int l = 0;
}
else{
int edge_width = count;
statistic.push_back(edge_width);
count = 0;
}
}
}
}
map<int, int>m;
/*求得不同的强边缘的宽度以及对应的个数*/
for (int i = 0; i < statistic.size(); i++)
{
if (m.end() != m.find(statistic[i]))
{
m[statistic[i]]++;
}
else{
m.insert(pair<int, int>(statistic[i], 1));
}
}
for (auto it : m)
{
cout << it.first << ends << it.second << endl;
}
map<int, double>p;
map<int, int>::iterator iter;
/*for (iter = m.begin(); iter != m.end;iter++)
{
}*/
/*求得不同强边缘宽度所分别对应的概率*/
for (iter =m.begin(); iter != m.end(); iter++)
{
p.insert(pair<int, double>(iter->first, ((double)(iter->second) / (double)statistic.size())));
}
/*在屏幕上将边缘宽度和所对应的概率输出*/
for (auto ite : p)
{
cout << ite.first << ends << ite.second << endl;
}
sprintf(name, "E:/03.jpg");
imwrite(name, binary_img);
imshow("【水平方向梯度二值化图】 X方向Sobel", binary_img);
waitKey(0);
int max_value = 0;//概率最大的边缘宽度
int max_value_pro = 0;
int max_value_edge = 0;//最大的边缘宽度
/*求概率最大的边缘宽度和最大的边缘宽度*/
map<int, int>::iterator point;
for (point = m.begin(); point != m.end(); point++)
{
if (point->second > max_value_pro)
{
max_value_pro = point->second;
max_value = point->first;
}
if (point->first > max_value_edge)
{
max_value_edge = point->first;
}
}
printf("max_value=%d\n", max_value);
printf("max_value_edge=%d\n", max_value_edge);
/*到这里结束*/
/*距离因子的计算以及清晰度评价值的计算*/
double metric = 0;
map<int, double>::iterator itera;
for (itera = p.begin(); itera != p.end(); itera++)
{
if (itera->first < max_value)
{
double distance_factor = ((double)(itera->first) / (double)(max_value))*((double)(itera->first) / (double)(max_value));
metric += distance_factor*(itera->first)*(itera->second);
}
else if (itera->first == max_value)
{
double distance_factor = 1;
metric += distance_factor*(itera->first)*(itera->second);
}
else{
double distance_factor = ((double)(max_value_edge - itera->first) / (double)(max_value_edge - max_value))*((double)(max_value_edge - itera->first) / (double)(max_value_edge - max_value));
metric += distance_factor*(itera->first)*(itera->second);
}
}
printf("metric=%lf\n", metric);
/*到这里结束*/
cout << max_value << endl;
cout << max_value_edge << endl;
return 0;
}
sharpen
最新推荐文章于 2023-03-10 15:00:45 发布