从电脑上读入的灰度图像,并分别计算图像的均值、方差等统计特征,并计算图像的直方图特征并以图形方式显示图像的直方图(用C或C++语言实现)不能用opencv和其他现成的库函数操作;。
时间: 2024-02-12 16:07:15 浏览: 196
zhifangtu.rar_opencv 均值_opencv 方差_opencv均值_求 灰度直方图
好的,以下是一个计算灰度图像均值、方差和直方图的代码示例,以及用gnuplot绘制直方图的方法:
```c++
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
// BMP文件头结构体
#pragma pack(push, 1)
struct BMPHeader {
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
};
#pragma pack(pop)
// BMP信息头结构体
struct BMPInfoHeader {
uint32_t biSize;
int32_t biWidth;
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
};
// 读取灰度图像数据
unsigned char* read_gray_bmp(const char* filename, int& width, int& height) {
std::ifstream file(filename, std::ios::binary);
if (!file) {
std::cerr << "Error: cannot open file \"" << filename << "\"" << std::endl;
return nullptr;
}
BMPHeader header;
BMPInfoHeader info_header;
// 读取文件头和信息头
file.read((char*)&header, sizeof(header));
file.read((char*)&info_header, sizeof(info_header));
// 检查文件类型是否为BMP
if (header.bfType != 0x4d42) {
std::cerr << "Error: \"" << filename << "\" is not a BMP file" << std::endl;
return nullptr;
}
// 检查位图压缩类型是否为无压缩
if (info_header.biCompression != 0) {
std::cerr << "Error: \"" << filename << "\" is a compressed BMP file" << std::endl;
return nullptr;
}
// 检查像素位数是否为8
if (info_header.biBitCount != 8) {
std::cerr << "Error: \"" << filename << "\" is not a gray BMP file" << std::endl;
return nullptr;
}
// 读取调色板
unsigned char palette[1024];
file.read((char*)palette, sizeof(palette));
// 读取图像数据
width = info_header.biWidth;
height = info_header.biHeight;
int row_size = ((width * info_header.biBitCount + 31) / 32) * 4;
unsigned char* data = new unsigned char[width * height];
file.seekg(header.bfOffBits, std::ios::beg);
for (int y = 0; y < height; ++y) {
file.read((char*)(data + width * (height - y - 1)), width);
file.seekg(row_size - width, std::ios::cur);
}
return data;
}
// 计算均值和方差
void calc_mean_variance(const unsigned char* data, int width, int height, double& mean, double& variance) {
int count = width * height;
double sum = 0.0, sum2 = 0.0;
for (int i = 0; i < count; ++i) {
sum += data[i];
sum2 += data[i] * data[i];
}
mean = sum / count;
variance = sum2 / count - mean * mean;
}
// 计算直方图
std::vector<int> calc_histogram(const unsigned char* data, int width, int height, int num_bins) {
int count = width * height;
std::vector<int> histogram(num_bins);
int bin_size = 256 / num_bins;
for (int i = 0; i < count; ++i) {
int bin = data[i] / bin_size;
if (bin >= num_bins) {
bin = num_bins - 1;
}
++histogram[bin];
}
return histogram;
}
// 绘制直方图
void plot_histogram(const std::vector<int>& histogram) {
// 生成gnuplot脚本文件
std::ofstream gnufile("histogram.gnu");
gnufile << "set terminal pngcairo size 800,600" << std::endl;
gnufile << "set output \"histogram.png\"" << std::endl;
gnufile << "set boxwidth 0.9" << std::endl;
gnufile << "set style fill solid" << std::endl;
gnufile << "unset key" << std::endl;
gnufile << "plot '-' using 1:2 with boxes lc rgb \"#808080\"" << std::endl;
for (int i = 0; i < histogram.size(); ++i) {
gnufile << i << ' ' << histogram[i] << std::endl;
}
gnufile << "e" << std::endl;
// 执行gnuplot脚本并生成直方图
system("gnuplot histogram.gnu");
}
int main() {
int width, height;
unsigned char* data = read_gray_bmp("image.bmp", width, height);
if (!data) {
return 1;
}
double mean, variance;
calc_mean_variance(data, width, height, mean, variance);
std::cout << "Mean: " << mean << std::endl;
std::cout << "Variance: " << variance << std::endl;
std::vector<int> histogram = calc_histogram(data, width, height, 16);
plot_histogram(histogram);
delete[] data;
return 0;
}
```
在这个例子中,我们首先读取灰度图像数据,然后计算图像的均值和方差,并计算图像的直方图。为了绘制直方图,我们使用gnuplot生成一个脚本文件,然后执行该脚本文件,生成PNG格式的直方图图像。您需要安装gnuplot来运行这个例子。希望这可以帮助您解决问题!
阅读全文