基于深度学习的图像的风格迁移创新实训8

xiaoxiao2021-03-01  12

基于上周的工作,我继续研究了第五种算法:全局LBP算法。

对一张图像中的每个像素,计算其相邻的八个像素与它的像素值比较,得到一个0和1组成八位的码;这个码可以表达局部特征。那么这个码值的取值有2的八次方即256中选择,可以组成一个256个bin的直方图。使得我们可以使用基于直方图的相似度度量方法来衡量lbp下两张图片的相似度。

string Texture_global_LBP(int srcPicNum, int mode) { Mat src, graySrc; int hist[256]; memset(hist, 0, 256 * sizeof(int)); if (mode == 0) { src = imread(getPath(srcPicNum), CV_LOAD_IMAGE_COLOR); } else { src = UserChosenMat; } cvtColor(src, graySrc, CV_RGB2GRAY); resize(graySrc, graySrc, Size(graySrc.rows/4, graySrc.rows/4)); int total = (graySrc.rows - 2)*(graySrc.cols - 2); int neighbor[8];//左上角,顺时针,到左边 for (int i = 1; i < graySrc.rows-1; i++) { for (int j = 1; j < graySrc.cols - 1; j++) { memset(neighbor, 0, 8 * sizeof(int)); uchar mid = graySrc.at<uchar>(i, j); neighbor[0] = (graySrc.at<uchar>(i - 1, j - 1) > mid) ? 1 : 0; neighbor[1] = (graySrc.at<uchar>(i - 1, j) > mid) ? 1 : 0; neighbor[2] = (graySrc.at<uchar>(i - 1, j + 1) > mid) ? 1 : 0; neighbor[3] = (graySrc.at<uchar>(i, j + 1) > mid) ? 1 : 0; neighbor[4] = (graySrc.at<uchar>(i + 1, j + 1) > mid) ? 1 : 0; neighbor[5] = (graySrc.at<uchar>(i + 1, j ) > mid) ? 1 : 0; neighbor[6] = (graySrc.at<uchar>(i + 1, j - 1) > mid) ? 1 : 0; neighbor[7] = (graySrc.at<uchar>(i, j - 1) > mid) ? 1 : 0; int bin = 0; for (int t = 0; t < 8; t++) { bin *= 2; bin += neighbor[t]; } hist[bin]++; } } string result = to_string(total); result.push_back(','); for (int i = 0; i < 256; i++) { result.append(to_string(hist[i])); if (i != 255) result.push_back(','); } //cout << result << endl; return result; }

检索:

int Retrieval_Texture_lbp() { ifstream in; in.open("texture_lbp.txt", ios::in); if (in.fail()) return -1; string lbp = Texture_global_LBP(-1, TEST_MODE); double dstArr[256]; vector<string> strvec = split(lbp, ","); int total = stoi(strvec[0]); for (int i = 0; i < 255; i++) { dstArr[i] = (double)(stoi(strvec[i + 1]))/(double)total; } string line; double maxRes = 0; int winner = -1; double res = 0; double curbin; for (int i = 1; i <= MAX_PICNNUM; i++) { getline(in, line, '\n'); res = 0; strvec.clear(); strvec = split(line, ","); total = stoi(strvec[0]); for (int i = 0; i < 255; i++) { curbin = (double)(stoi(strvec[i + 1])) / (double)total; res += min(curbin, dstArr[i]); } if (res>maxRes) { cout << maxRes << endl; maxRes = res; winner = i; } if (i % 200 == 0) cout << "处理完毕" << i << endl; } cout << "lbp算法选出的图片是:" << winner << endl; cout << "结果数值是" << maxRes << endl; return winner; }

经过试验,发现全局lbp算法对于人脸检测效果很好,但对于一般的图片表现一般,且检索速度较慢。于是经过比较,我决定融合hsv直方图和灰度共生矩阵方法,作为最终网站使用的检索系统的检索方法。

int Retrieval_both() { ifstream inh; inh.open("E:\\programming\\C++workbench\\test\\Image_Retrieval\\Image_Retrieval\\color_hsvhist.txt", ios::in); if (inh.fail()) return -1; string hsvcode = Color_hsv_hist(-1, TEST_MODE); int dstArr[64], curArr[64]; memset(dstArr, 0, 64 * sizeof(int)); memset(curArr, 0, 64 * sizeof(int)); vector<string> strvech = split_str(hsvcode, ","); for (int i = 0; i < 64; i++) { dstArr[i] = stoi(strvech[i]); } string line; ifstream ing; double min[4], range[4]; //ing.open("texture_glcm_minmax.txt", ios::in); //getline(ing, line, '\n'); //vector<string> minstr = split(line, ","); //getline(ing, line, '\n'); //vector<string> maxstr = split(line, ","); for (int i = 0; i < 4; i++) { min[i] = min_glcm_feature[i]; range[i] = max_glcm_feature[i] - min_glcm_feature[i]; } //ing.close(); ing.open("E:\\programming\\C++workbench\\test\\Image_Retrieval\\Image_Retrieval\\texture_glcm.txt", ios::in); if (ing.fail()) return -1; string gclm_feature = Texture_GLCM(-1, TEST_MODE); vector<string> strvecg = split_str(gclm_feature, ","); double vec[4]; double alen = 0; for (int i = 0; i < 4; i++) { vec[i] = (stod(strvecg[i]) - min[i]) / range[i]; alen += vec[i] * vec[i]; } alen = sqrt(alen); double maxRes = -2; double cosRes = 0; double curvec[4]; double blen = 0; double product = 0; int winner = -1; int res = 0; double curRes = 0.0; for (int i = 1; i <= MAX_PICNNUM; i++) { if (i % 100 == 0) cout << i << " 处理完成" << endl; getline(inh, line, '\n'); res = 0; curRes = 0; memset(curArr, 0, 64 * sizeof(int)); strvech.clear(); strvech = split_str(line, ","); for (int i = 0; i < 64; i++) { curArr[i] = stoi(strvech[i]); res += (int)(sqrt(curArr[i] * dstArr[i])); } curRes += 1 * (double)res / (45 * 45); getline(ing, line, '\n'); cosRes = 0; blen = 0; product = 0; strvecg.clear(); strvecg = split_str(line, ","); for (int i = 0; i < 4; i++) { curvec[i] = (stod(strvecg[i]) - min[i]) / range[i]; product += curvec[i] * vec[i]; blen += curvec[i] * curvec[i]; } blen = sqrt(blen); cosRes = product / (alen*blen); curRes += 1 * cosRes; if (curRes > maxRes) { cout << i << " : " << maxRes << endl; maxRes = curRes; winner = i; } } cout << "联合算法选出的图片是:" << winner << endl; cout << setprecision(14) << "总相似度是" << maxRes << endl; return winner; }对这个代码进行一个简单的封装,使得它可以接受一个原始图片地址和一个想要保存的目标图片地址,这样网站就可以使用系统命令行对该程序进行调用了。
转载请注明原文地址: https://www.6miu.com/read-3450211.html

最新回复(0)