我正在尝试使用均匀圆形 LBP(1 个单位半径邻域中的 8 个点)实现基本的人脸识别系统。 我正在拍摄一张图片,将其大小调整为 200 x 200 像素,然后将图片拆分为 8x8 小图片。然后我计算每个小图像的直方图并获得直方图列表。为了比较 2 张图像,我计算相应直方图之间的卡方距离并生成分数。
这是我的统一 LBP 实现:
import numpy as np
import math
uniform = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 58, 6: 5, 7: 6, 8: 7, 9: 58, 10: 58, 11: 58, 12: 8, 13: 58, 14: 9, 15: 10, 16: 11, 17: 58, 18: 58, 19: 58, 20: 58, 21: 58, 22: 58, 23: 58, 24: 12, 25: 58, 26: 58, 27: 58, 28: 13, 29: 58, 30: 14, 31: 15, 32: 16, 33: 58, 34: 58, 35: 58, 36: 58, 37: 58, 38: 58, 39: 58, 40: 58, 41: 58, 42: 58, 43: 58, 44: 58, 45: 58, 46: 58, 47: 58, 48: 17, 49: 58, 50: 58, 51: 58, 52: 58, 53: 58, 54: 58, 55: 58, 56: 18, 57: 58, 58: 58, 59: 58, 60: 19, 61: 58, 62: 20, 63: 21, 64: 22, 65: 58, 66: 58, 67: 58, 68: 58, 69: 58, 70: 58, 71: 58, 72: 58, 73: 58, 74: 58, 75: 58, 76: 58, 77: 58, 78: 58, 79: 58, 80: 58, 81: 58, 82: 58, 83: 58, 84: 58, 85: 58, 86: 58, 87: 58, 88: 58, 89: 58, 90: 58, 91: 58, 92: 58, 93: 58, 94: 58, 95: 58, 96: 23, 97: 58, 98: 58, 99: 58, 100: 58, 101: 58, 102: 58, 103: 58, 104: 58, 105: 58, 106: 58, 107: 58, 108: 58, 109: 58, 110: 58, 111: 58, 112: 24, 113: 58, 114: 58, 115: 58, 116: 58, 117: 58, 118: 58, 119: 58, 120: 25, 121: 58, 122: 58, 123: 58, 124: 26, 125: 58, 126: 27, 127: 28, 128: 29, 129: 30, 130: 58, 131: 31, 132: 58, 133: 58, 134: 58, 135: 32, 136: 58, 137: 58, 138: 58, 139: 58, 140: 58, 141: 58, 142: 58, 143: 33, 144: 58, 145: 58, 146: 58, 147: 58, 148: 58, 149: 58, 150: 58, 151: 58, 152: 58, 153: 58, 154: 58, 155: 58, 156: 58, 157: 58, 158: 58, 159: 34, 160: 58, 161: 58, 162: 58, 163: 58, 164: 58, 165: 58, 166: 58, 167: 58, 168: 58, 169: 58, 170: 58, 171: 58, 172: 58, 173: 58, 174: 58, 175: 58, 176: 58, 177: 58, 178: 58, 179: 58, 180: 58, 181: 58, 182: 58, 183: 58, 184: 58, 185: 58, 186: 58, 187: 58, 188: 58, 189: 58, 190: 58, 191: 35, 192: 36, 193: 37, 194: 58, 195: 38, 196: 58, 197: 58, 198: 58, 199: 39, 200: 58, 201: 58, 202: 58, 203: 58, 204: 58, 205: 58, 206: 58, 207: 40, 208: 58, 209: 58, 210: 58, 211: 58, 212: 58, 213: 58, 214: 58, 215: 58, 216: 58, 217: 58, 218: 58, 219: 58, 220: 58, 221: 58, 222: 58, 223: 41, 224: 42, 225: 43, 226: 58, 227: 44, 228: 58, 229: 58, 230: 58, 231: 45, 232: 58, 233: 58, 234: 58, 235: 58, 236: 58, 237: 58, 238: 58, 239: 46, 240: 47, 241: 48, 242: 58, 243: 49, 244: 58, 245: 58, 246: 58, 247: 50, 248: 51, 249: 52, 250: 58, 251: 53, 252: 54, 253: 55, 254: 56, 255: 57}
def bilinear_interpolation(i, j, y, x, img):
fy, fx = int(y), int(x)
cy, cx = math.ceil(y), math.ceil(x)
# calculate the fractional parts
ty = y - fy
tx = x - fx
w1 = (1 - tx) * (1 - ty)
w2 = tx * (1 - ty)
w3 = (1 - tx) * ty
w4 = tx * ty
return w1 * img[i + fy, j + fx] + w2 * img[i + fy, j + cx] + \
w3 * img[i + cy, j + fx] + w4 * img[i + cy, j + cx]
def thresholded(center, pixels):
out = []
for a in pixels:
if a > center:
out.append(1)
else:
out.append(0)
return out
def uniform_circular(img, P, R):
ysize, xsize = img.shape
transformed_img = np.zeros((ysize - 2 * R,xsize - 2 * R), dtype=np.uint8)
for y in range(R, len(img) - R):
for x in range(R, len(img[0]) - R):
center = img[y,x]
pixels = []
for point in range(0, P):
r = R * math.cos(2 * math.pi * point / P)
c = R * math.sin(2 * math.pi * point / P)
pixels.append(bilinear_interpolation(y, x, r, c, img))
values = thresholded(center, pixels)
res = 0
for a in range(0, P):
res += values[a] << a
transformed_img.itemset((y - R,x - R), uniform[res])
transformed_img = transformed_img[R:-R,R:-R]
return transformed_img
我在 AT&T database 上做了一个实验每个主题拍摄 2 张图库图像和 8 张探测图像。实验的 ROC 结果是:
在上述 ROC 中,x 轴表示错误接受率,y 轴表示真实接受率。根据统一 LBP 标准,准确性似乎很差。我确定我的实现有问题。如果有人可以帮助我,那就太好了。感谢阅读。
编辑:
我想我在上面的代码中犯了一个错误。我顺时针方向走,而关于 LBP 的论文建议我在分配权重时应该逆时针方向走。行:c = R * math.sin(2 * math.pi * point/P) 应该是 c = -R * math.sin(2 * math.pi * point/P)。编辑后的结果更糟。这表明我的代码有问题。我想我选择插值坐标的方式搞砸了。
编辑:接下来我尝试复制@bytefish 的代码here并使用uniform hashmap实现Uniform Circular LBP。
def uniform_circular(img, P, R):
ysize, xsize = img.shape
transformed_img = np.zeros((ysize - 2 * R,xsize - 2 * R), dtype=np.uint8)
for point in range(0, P):
x = R * math.cos(2 * math.pi * point / P)
y = -R * math.sin(2 * math.pi * point / P)
fy, fx = int(y), int(x)
cy, cx = math.ceil(y), math.ceil(x)
# calculate the fractional parts
ty = y - fy
tx = x - fx
w1 = (1 - tx) * (1 - ty)
w2 = tx * (1 - ty)
w3 = (1 - tx) * ty
w4 = tx * ty
for i in range(R, ysize - R):
for j in range(R, xsize - R):
t = w1 * img[i + fy, j + fx] + w2 * img[i + fy, j + cx] + \
w3 * img[i + cy, j + fx] + w4 * img[i + cy, j + cx]
center = img[i,j]
pixels = []
res = 0
transformed_img[i - R,j - R] += (t > center) << point
for i in range(R, ysize - R):
for j in range(R, xsize - R):
transformed_img[i - R,j - R] = uniform[transformed_img[i - R,j - R]]
这是相同的 ROC:
我尝试用 C++ 实现相同的代码。这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
using namespace cv;
int* uniform_circular_LBP_histogram(Mat& src) {
int i, j;
int radius = 1;
int neighbours = 8;
Size size = src.size();
int *hist_array = (int *)calloc(59,sizeof(int));
int uniform[] = {0,1,2,3,4,58,5,6,7,58,58,58,8,58,9,10,11,58,58,58,58,58,58,58,12,58,58,58,13,58,14,15,16,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,17,58,58,58,58,58,58,58,18,58,58,58,19,58,20,21,22,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,23,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,24,58,58,58,58,58,58,58,25,58,58,58,26,58,27,28,29,30,58,31,58,58,58,32,58,58,58,58,58,58,58,33,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,34,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,35,36,37,58,38,58,58,58,39,58,58,58,58,58,58,58,40,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,41,42,43,58,44,58,58,58,45,58,58,58,58,58,58,58,46,47,48,58,49,58,58,58,50,51,52,58,53,54,55,56,57};
Mat dst = Mat::zeros(size.height - 2 * radius, size.width - 2 * radius, CV_8UC1);
for (int n = 0; n < neighbours; n++) {
float x = static_cast<float>(radius) * cos(2.0 * M_PI * n / static_cast<float>(neighbours));
float y = static_cast<float>(radius) * -sin(2.0 * M_PI * n / static_cast<float>(neighbours));
int fx = static_cast<int>(floor(x));
int fy = static_cast<int>(floor(y));
int cx = static_cast<int>(ceil(x));
int cy = static_cast<int>(ceil(x));
float ty = y - fy;
float tx = y - fx;
float w1 = (1 - tx) * (1 - ty);
float w2 = tx * (1 - ty);
float w3 = (1 - tx) * ty;
float w4 = 1 - w1 - w2 - w3;
for (i = 0; i < 59; i++) {
hist_array[i] = 0;
}
for (i = radius; i < size.height - radius; i++) {
for (j = radius; j < size.width - radius; j++) {
float t = w1 * src.at<uchar>(i + fy, j + fx) + \
w2 * src.at<uchar>(i + fy, j + cx) + \
w3 * src.at<uchar>(i + cy, j + fx) + \
w4 * src.at<uchar>(i + cy, j + cx);
dst.at<uchar>(i - radius, j - radius) += ((t > src.at<uchar>(i,j)) && \
(abs(t - src.at<uchar>(i,j)) > std::numeric_limits<float>::epsilon())) << n;
}
}
}
for (i = radius; i < size.height - radius; i++) {
for (j = radius; j < size.width - radius; j++) {
int val = uniform[dst.at<uchar>(i - radius, j - radius)];
dst.at<uchar>(i - radius, j - radius) = val;
hist_array[val] += 1;
}
}
return hist_array;
}
int main( int argc, char** argv )
{
Mat src;
int i,j;
src = imread( argv[1], 0 );
if( argc != 2 || !src.data )
{
printf( "No image data \n" );
return -1;
}
const int width = 200;
const int height = 200;
Size size = src.size();
Size new_size = Size();
new_size.height = 200;
new_size.width = 200;
Mat resized_src;
resize(src, resized_src, new_size, 0, 0, INTER_CUBIC);
int count = 1;
for (i = 0; i <= width - 8; i += 25) {
for (j = 0; j <= height - 8; j += 25) {
Mat new_mat = resized_src.rowRange(i, i + 25).colRange(j, j + 25);
int *hist = uniform_circular_LBP_histogram(new_mat);
int z;
for (z = 0; z < 58; z++) {
std::cout << hist[z] << ",";
}
std::cout << hist[z] << "\n";
count += 1;
}
}
return 0;
}
相同的 ROC:
我还做了一个基于排名的实验。并得到这条CMC曲线。
关于 CMC 曲线的一些细节:X 轴代表等级。 (1-10) 和 Y 轴表示精度 (0-1)。所以,我得到了 80% 以上的 Rank1 准确率。
最佳答案
我不知道 python,但很可能您的代码已损坏。
我的建议是,点击这两个链接,并尝试将其中一个 C++ 代码移植到 python。第一个链接还包含一些关于 LBP 的信息。
http://www.bytefish.de/blog/local_binary_patterns/
https://github.com/berak/uniform-lbp
还有一件事我可以说,你说你正在将图像调整为 200x200。你为什么要那样做?据我所知,AT&T 图片比那个小,你只是让图片变大,但我认为这不会帮助你,而且它可能会对性能产生负面影响。
关于c++ - Uniform Circular LBP人脸识别实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20581267/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg