快捷搜索:  汽车  科技

图像连通域分析算法(计算机视觉学习笔记7)

图像连通域分析算法(计算机视觉学习笔记7)openc提供了四种检测方法:相关性:HISTCMP_CORREL 卡方:HISTCMP_CHISQR 交叉HISTCMP_INTERSECT 巴氏距离:HISTCMP_BHATTACHARYYAc 操作稍显复杂,需要先进行彩色空间变换,变为hsv空间(一般而言直方图在hsv空间进行处理效果比较好),再获取直方图,然后进行归一化,才能进行检测。img1 = imread('data/IMG1.bmp'); img2 = imread('data/IMG2.bmp'); gray1 = rgb2gray(img1); gray2 = rgb2gray(img2); subplot(1 2 1); imshow(gray1); subplot(1 2 2); imshow(gray2); r = corr2(gray1 gray2); fprintf('两图像相似性: %f'

通过直方图对两幅图像进行比较,就是就是直方图数据,比较两幅图像的直方图的相似性,然后得出两图的相似系数。

这是早期图像检测的常用技术手段,通常与图像特征值,边缘检测等方法结合,可以简单迅速分析出两幅图像是否相似。

在MATLAB中,一般用函数 corr2()计算两图相关系数,要求图像为灰度图像,并且尺寸相同。而opencv就人性化很多了,采用compareHist()函数检测图像相似性,可以直接检测彩色图像,不要求图像尺寸,而且还提供了四种检测方法,然而有三种方法很坑,基本可以忽略。

MATLAB比较两图相似性

代码很简单,注意把彩色图像转为灰度图像即可

img1 = imread('data/IMG1.bmp'); img2 = imread('data/IMG2.bmp'); gray1 = rgb2gray(img1); gray2 = rgb2gray(img2); subplot(1 2 1); imshow(gray1); subplot(1 2 2); imshow(gray2); r = corr2(gray1 gray2); fprintf('两图像相似性: %f' r)

因为采用的是灰度图像,损失了两个像素通道,所以检测效果较差

图像连通域分析算法(计算机视觉学习笔记7)(1)

灰度图

图像连通域分析算法(计算机视觉学习笔记7)(2)

接近77%的相似性

c 比较两图相似性

c 操作稍显复杂,需要先进行彩色空间变换,变为hsv空间(一般而言直方图在hsv空间进行处理效果比较好),再获取直方图,然后进行归一化,才能进行检测。

openc提供了四种检测方法:相关性:HISTCMP_CORREL 卡方:HISTCMP_CHISQR 交叉HISTCMP_INTERSECT 巴氏距离:HISTCMP_BHATTACHARYYA

#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc char** argv) { Mat img1 = imread("data/images/IMG1.bmp"); Mat img2 = imread("data/images/IMG2.bmp"); imshow("image1" img1); imshow("image2" img2); // 色彩空间转换 Mat hsv1 hsv2 hsv3 hsv4; cvtColor(img1 hsv1 COLOR_BGR2HSV); cvtColor(img2 hsv2 COLOR_BGR2HSV); // 定义直方图参数,详情见calHist使用文档 int h_bins = 60; int s_bins = 64; int histSize[] = { h_bins s_bins }; float h_ranges[] = { 0 180 }; float s_ranges[] = { 0 256 }; const float* ranges[] = { h_ranges s_ranges }; int channels[] = { 0 1 }; // 只取前两个颜色通道 // 获取直方图 Mat hist1 hist2 hist3 hist4; calcHist(&hsv1 1 channels Mat() hist1 2 histSize ranges true false); calcHist(&hsv2 1 channels Mat() hist2 2 histSize ranges true false); // 直方图均衡化 normalize(hist1 hist1 0 1 NORM_MINMAX -1 Mat()); normalize(hist2 hist2 0 1 NORM_MINMAX -1 Mat()); // 进行图像比较,测试四种方法 for (int i = 0; i < 4; i ) { int compare_method = i; double img1_img2 = compareHist(hist1 hist2 compare_method); cout << "比较方法: " << i << " 图像相似性: " << img1_img2 << endl; } waitKey(0); return 0; }

图像连通域分析算法(计算机视觉学习笔记7)(3)

彩色版的图像

图像连通域分析算法(计算机视觉学习笔记7)(4)

相似性检测结果

很明显,彩色图像比灰度图像检测效果更好,而且采用相关性的方法检测比较靠谱,后面三种方法只在特定情况下才有用,基本可以忽略。

python比较两图相似性

和c 基本一样,hsv转换,归一化等。不过不需要定义数据类型还是要方便很多

import cv2 as cv src1 = cv.imread("data/images/img1.jpg") src2 = cv.imread("data/images/img2.jpg") cv.imshow("image1" src1) cv.imshow("image2" src2) hsv1 = cv.cvtColor(src1 cv.COLOR_BGR2HSV) hsv2 = cv.cvtColor(src2 cv.COLOR_BGR2HSV) # [输入图像] , [图像通道], mask = None, bins值, 对应h和s通道像素值取值范围 hist1 = cv.calcHist([hsv1] [0 1] None [60 64] [0 180 0 256]) hist2 = cv.calcHist([hsv2] [0 1] None [60 64] [0 180 0 256]) # 图像归一化 cv.normalize(hist1 hist1 0 1.0 cv.NORM_MINMAX) cv.normalize(hist2 hist2 0 1.0 cv.NORM_MINMAX) for i in range(4): src1_src2 = cv.compareHist(hist1 hist2 i) print("比较方法:%s 图像相似性: %.2f" % (i src1_src2)) cv.waitKey(0) cv.destroyAllWindows()

图像连通域分析算法(计算机视觉学习笔记7)(5)

两张图片大小不一也能检测

图像连通域分析算法(计算机视觉学习笔记7)(6)

相似性检测结果

总结: 通过直方图进行图像比较,采用相关性分析一般能取的不错的效果,采用卡方,交叉,巴氏方法的肯定是逗比。

按这个更新速度过几天应该能更新到滤波吧

猜您喜欢: