这次给大家分享一个图像识别方面的小项目,主要功能是识别图像中的人脸并根据人脸在图片库找出同一个与它最相似的图片,也就是辨别不同的人。
环境:VS2013+opencv2.4.13
主要是算法:opencv中人脸识别算法(截取人脸)+哈希算法(辨别人脸)
opencv中人脸识别算法:这个很常用,就是普通的人脸识别算法,直接上代码:
void IdentifyFace(Mat image) //识别并截取人脸 { CascadeClassifier ccf; ccf.load(xmlPath); vector<Rect> faces; Mat gray; cvtColor(image, gray, CV_BGR2GRAY); equalizeHist(gray, gray); //直方图均匀化 ccf.detectMultiScale(gray, faces, 1.1, 3, 0, Size(50, 50), Size(500, 500)); //检测人脸 for (vector<Rect>::const_iterator iter = faces.begin(); iter != faces.end(); iter++) { rectangle(image, *iter, Scalar(0, 0, 255), 2, 8); //画出脸部矩形 } for (size_t i = 0; i<faces.size(); i++) { Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2); image = image(Rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height)); } }
哈希算法:主要是用来视觉目标跟踪,主要的思路如下:
(1)缩小尺寸:pHash以小图片开始,但图片大于8*8,32*32是最好的。这样做的目的是简化了DCT的计算,而不是减小频率。
(2)简化色彩:将图片转化成灰度图像,进一步简化计算量。
(3)计算DCT:计算图片的DCT变换,得到32*32的DCT系数矩阵。
(4)缩小DCT:虽然DCT的结果是32*32大小的矩阵,但我们只要保留左上角的8*8的矩阵,这部分呈现了图片中的最低频率。
(5)计算平均值:如同均值哈希一样,计算DCT的均值。
(6)计算hash值:这是最主要的一步,根据8*8的DCT矩阵,设置0或1的64位的hash值,大于等于DCT均值的设为”1”,小于DCT均值的设为“0”。组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。
结果并不能告诉我们真实性的低频率,只能粗略地告诉我们相对于平均值频率的相对比例。只要图片的整体结构保持不变,hash结果值就不变。能够避免伽马校正或颜色直方图被调整带来的影响。
pHash同样可以用汉明距离来进行比较。(只需要比较每一位对应的位置并算计不同的位的个数)
代码:
string calHashValue(Mat &src) //得到图片的哈希值 { string zeroonestr(64, '