#include "opencv2/core.hpp"//引入opencv库函数,这里我用的是opencv3.6的
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include
#include
#include
#include
#include
#include "opencv/cv.h"
#include "opencv/highgui.h"
using namespace std;
using namespace cv;
cv::Mat GDAL2Mat(const char* fileName);
void fcmmem(cv::InputArray image, cv::OutputArray uu, cv::OutputArray uc);
void vec_mat(int k, int A, int i, int j);
double MOD(double x, double y);
void ClustFCM(cv::InputArray image, cv::OutputArray U, cv::OutputArray obj_fcn, cv::OutputArray center, int cluster_n, float * option);
void initfcm(int cluster_n, int data_n, cv::OutputArray U);
void stepfcm(cv::InputArray data, int cluster_n, int expo, double *obj_fcn_one, cv::OutputArray center, cv::OutputArray U);
void final_map(cv::InputArray imx, cv::InputArray uu, cv::InputArray uc, cv::OutputArray imf);
//这个是只用了VS写的,不涉及MFC界面操作
int main(int argc, char* argv[])
{
Mat img1;//第一时相影像
Mat img2;//第二时相影像
const char* filename1 = "B1.tif";
img1 = GDAL2Mat(filename1);
const char* filename2 = "B2.tif";
img2 = GDAL2Mat(filename2);
int k = img1.dims;
int m = img1.rows;
int n = img1.cols;
Mat img_save = img1;
int w_mean_var = 5;
int w_half = (w_mean_var - 1) / 2;
vector
split(img1, band1);
if (!img1.data)
{
cout << " cannot open!" << endl;
return -1;
}
vector
split(img2, band2);
if (!img2.data)
{
cout << " cannot open!" << endl;
return -1;
}
Mat b1 = (band2[0] - band1[0]).mul(band2[0] - band1[0]);
Mat b2 = (band2[1] - band1[1]).mul(band2[1] - band1[1]);
Mat b3 = (band2[2] - band1[2]).mul(band2[2] - band1[2]);
Mat b4 = (band2[3] - band1[3]).mul(band2[3] - band1[3]);
Mat a = Mat::zeros(m, n, CV_64FC1);
Mat he = b1 + b2 + b3 + b4;
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
a.at
}
}
double amin = 0, amax = 0;
cv::Point minPt, maxPt;
minMaxLoc(a, &amin, &amax, &minPt, &maxPt);
Mat cva = 255.0f*(a - amin) / (amax - amin);
Mat uu;
Mat uc;
fcmmem(cva, uu, uc);
Mat imf;
final_map(cva,uu,uc,imf);
namedWindow("最终差异图imf", WINDOW_NORMAL);
imshow("最终差异图imf", imf);
img1.release();
img2.release();
img3.release();
waitKey(0);
return 0;
}
void final_map(cv::InputArray imx, cv::InputArray uu, cv::InputArray uc, cv::OutputArray imf){
Mat im = imx.getMat();
int A = im.rows;
int B = im.cols;
Mat mf = Mat::zeros(A, B, CV_8U);
Mat u = uu.getMat();
Mat c = uc.getMat();
for (int i = 0; i < A; i++){
for (int j = 0; j < B; j++){
if (u.at
mf.at
}
if (c.at
mf.at
}
}
}
mf.copyTo(imf);
}
void fcmmem(cv::InputArray image, cv::OutputArray uu, cv::OutputArray uc){
Mat im = image.getMat();
int k = im.dims;
int A = im.rows;
int B = im.cols;
int N = A*B;
Mat imm = im.t();
Mat im1 = imm.reshape(0, N).clone();
int cluster_n = 2;
float options[4] = { 2.0f, 100.0f, 0.001f, 0.0f };
Mat center;//[cluster_n,1]
Mat U;//[cluster_n,N]
Mat obj_fcn;
ClustFCM(im1, U, obj_fcn, center, cluster_n, options);
Mat u = Mat::zeros(A, B, CV_32F);
Mat c = Mat::zeros(A, B, CV_32F);
for (int j = 0; j < B; j++){
for (int i = 0; i < A; i++){
if (center.at
u.at
c.at
}
else{
u.at
c.at
}
}
}
u.copyTo(uu);
c.copyTo(uc);
}
void ClustFCM(cv::InputArray image, cv::OutputArray U, cv::OutputArray obj_fcn, cv::OutputArray center, int cluster_n, float * option)
{
Mat data = image.getMat();
int data_n = data.rows;
int in_n = data.cols;
int expo = (int)option[0];
int max_iter = (int)option[1];
float min_impro = option[2];
int display = (int)option[3];
initfcm(cluster_n, data_n, U);
Mat obj_fcn_begin = Mat::zeros(max_iter, 1, CV_32F);
double obj_fcn_ones;
int iter_n;
for (int i = 1; i <= max_iter; i++)
{
stepfcm(data, cluster_n, expo, &obj_fcn_ones, center, U);
obj_fcn_begin.at
if (i > 1)
{
if (abs(obj_fcn_begin.at
{
iter_n = i;
break;
}
}
}
Mat obj_fcn_end = obj_fcn_begin(Range(0, iter_n), Range::all());
obj_fcn_end.copyTo(obj_fcn);
}
void initfcm(int cluster_n, int data_n, cv::OutputArray U)
{
Mat U_temp(cluster_n, data_n, CV_32F);
randu(U_temp, Scalar::all(0), Scalar::all(1));
//randu(U_temp, Scalar(0), Scalar(1));
Mat col_sum = U_temp.row(0) + U_temp.row(1);
Mat U_new(cluster_n, data_n, CV_32F);
U_new.row(0) = U_temp.row(0) / col_sum;
U_new.row(1) = U_temp.row(1) / col_sum;
U_new.copyTo(U);
}
void stepfcm(cv::InputArray data, int cluster_n, int expo, double *obj_fcn_one, cv::OutputArray center, cv::OutputArray U)
{
Mat dt;
data.copyTo(dt);
dt.convertTo(dt, CV_32F);
Mat temp;
Mat mf;
pow(U.getMat(), expo, mf);
reduce(mf, temp, 1, CV_REDUCE_SUM);
transpose(temp, temp);
Mat res = (Mat::ones(data.getMat().cols, 1, CV_32F)) * temp;
transpose(res, res);
Mat result = (mf*dt) / res;
result.copyTo(center);
Mat dist = Mat::zeros(result.rows, dt.rows, CV_32F);
for (int k = 0; k < result.rows; k++)
{
Mat temp = abs(dt - Mat::ones(data.getMat().rows, 1, CV_32F) * result(Range(k, k + 1), Range::all()));
transpose(temp, temp);
dist(Range(k, k + 1), Range::all()) = dist(Range(k, k + 1), Range::all()) + temp;
}
*obj_fcn_one = sum(dist.mul(dist).mul(mf))[0];
Mat tmp;
pow(dist, (-2 / (expo - 1)), tmp);
Mat Tmp;
reduce(tmp, Tmp, 0, CV_REDUCE_SUM);
Mat U_new = tmp.mul(1 / ((Mat::ones(cluster_n, 1, CV_32F)) * Tmp));
U_new.copyTo(U);//double
}
cv::Mat GDAL2Mat(const char* fileName)
{
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
GDALDataset * poDataset;
poDataset = (GDALDataset*)GDALOpen(fileName, GA_ReadOnly);
int Cols = poDataset->GetRasterXSize();
int Rows = poDataset->GetRasterYSize();
int BandSize = poDataset->GetRasterCount();
double *adfGeoTransform = new double[6];
poDataset->GetGeoTransform(adfGeoTransform);
std::vector
float* pafScan = (float*)CPLMalloc(sizeof(float)* Cols);
for (int i = 0; i< BandSize; i++)
{
GDALRasterBand *pBand = poDataset->GetRasterBand(i + 1);
pafScan = new float[Cols*Rows];
pBand->RasterIO(GF_Read, 0, 0, Cols, Rows, pafScan, Cols, Rows, GDT_Float32, 0, 0);
cv::Mat A = cv::Mat(Rows, Cols, CV_32FC1, pafScan);
imgMat.push_back(A.clone());
delete[]pBand;
A.release();
}
delete[] pafScan;
cv::Mat img;
img.create(Rows, Cols, CV_32FC(BandSize));
merge(imgMat, img);
//GDALClose((GDALDatasetH)poDataset);
imgMat.clear();
return img;
}
实现效果如下图所示: