图像检测

图像检测

1.算法描述

这里我用到三种处理方法:直接相关运算,归一化相关系数,以及像素点个数统计。

(1)直接作相关运算:

轮胎图像直接作为模板,和汽车图像直接做相关运算,即用公式:

得到的矩阵不在像素值表示范围内,所以还要除以一个系数(height * width * 255)来确保能输出图像。

但这种方法得到的相关系数矩阵转化而来的图像效果并不明显,而且如果一片与检测图像无关的区域比较亮,也会使得该区域的相关系数值较大。

(2)改进:归一化相关系数:

使用以下归一化相关系数矩阵的计算公式:

这样能得到一个元素范围在[-1, 1]的双精度浮点型矩阵,可以直接输出为图像。这次的效果明显好于上一次。

作归一化相关系数运算和直接作相关运算的对比:

(3)补充:自定义的基于像素个数统计的相关系数:

前两种方法还不能找出我们需要的4个轮胎的坐标,而我希望能在对应于每个轮胎的范围内能唯一地识别出一个像素点,于是我自定义了一个函数CountingCorrelation。

假设当前遍历到原图的(i, j)处,如果模板上的一个像素点的值和对应的原图位置上的像素值相差不超过一定范围(例如我选定的是5,这个数经多次选择,觉得5较合适),那么就在给新的矩阵中的(i, j)处的值加1。

这样,和模板的像素值越接近的原图中的一片等大的区域的核心对应在新矩阵中的值就越大。然后用一定方法将新矩阵的每个元素取值都映射到[0, 255]中(这里我用的方法是cor(i, j) = exp(cor(i, j) / 8),用指数函数能使得大值与小值之间的差变得更大,更有利于使匹配的轮胎的位置更亮更明显,系数8则是经过多次选择觉得较合适的数)。

最后经过这样处理,恰巧能使4个像素的值为255,经过分析它们大致分别对于于原图4个轮胎的中心位置。

2.Matlab代码

(1)函数Correlation:

Correlation.m

function correlation = Correlation(img, template)
    [h1,w1] = size(img);
    [h2,w2] = size(template);
    half_h = floor(h2 / 2);
    half_w = floor(w2 / 2);
    expand_img = zeros(h1 + h2 - 1, w1 + w2 - 1);
    expand_img((half_h + 1):(h1 + half_h), (half_w + 1):(w1 + half_w)) = img;
    expand_img = uint8(expand_img);
    correlation = zeros(h1 + h2 - 1, w1 + w2 - 1);
    for i = half_h + 1 : h1 + half_h
        for j = half_w + 1 : w1 + half_w
            for u = -half_h : half_h
                for v = -half_w : half_w
                    correlation(i, j) = correlation(i, j) + double(expand_img(i + u, j + v)) * double(template(half_h + 1 + u, half_w + 1 + v));
                end
            end  
        end
    end

    correlation = correlation(half_h + 1 : h1 + half_h, half_w + 1 : w1 + half_w);

(2)函数NormalizedCorrelation:

NormalizedCorrelation.m

function ncorr = NormalizedCorrelation(img, template)
    [h1,w1] = size(img);
    [h2,w2] = size(template);

    avrg_template = mean2(template(:));
    half_h = floor(h2 / 2);
    half_w = floor(w2 / 2);
    expand_img = zeros(h1 + h2 - 1, w1 + w2 - 1);
    expand_img((half_h + 1):(h1 + half_h), (half_w + 1):(w1 + half_w)) = img;
    expand_img = double(expand_img);
    template = double(template);
    ncorr = zeros(h1 + h2 - 1, w1 + w2 - 1);
    for i = half_h + 1 : h1 + half_h
        for j = half_w + 1 : w1 + half_w
            numerator = 0;
            denominator1 = 0;
            denominator2 = 0;
            avrg_img = mean2(expand_img(i - half_h : i + half_h, j - half_w : j + half_w));
            for u = -half_h : half_h
                for v = -half_w : half_w
                    numerator = numerator + (expand_img(i + u, j + v) - avrg_img) * (template(half_h + 1 + u, half_w + 1 + v) - avrg_template);
                    denominator1 = denominator1 + (template(half_h + 1 + u, half_w + 1 + v) - avrg_template) * (template(half_h + 1 + u, half_w + 1 + v) - avrg_template);
                    denominator2 = denominator2 + (expand_img(i + u, j + v) - avrg_img) * (expand_img(i + u, j + v) - avrg_img);
                end
            end
            ncorr(i, j) = numerator / sqrt(denominator1 * denominator2);
        end
    end

    ncorr = ncorr(half_h + 1 : h1 + half_h, half_w + 1 : w1 + half_w);

(3)函数CountingCorrelation:

CountingCorrelation.m

function cor = CountingCorrelation(img, template)
    [h1,w1] = size(img);
    [h2,w2] = size(template);
    half_h = floor(h2 / 2);
    half_w = floor(w2 / 2);

    expand_img = zeros(h1 + h2 - 1, w1 + w2 - 1);
    expand_img((half_h + 1):(h1 + half_h), (half_w + 1):(w1 + half_w)) = img;
    expand_img = uint8(expand_img);

    cor = zeros(h1, w1);
    for i = 1 : h1
        for j = 1 : w1
            for u = -half_h : half_h
                for v = -half_w : half_w
                    if i + u < 1 || j + v < 1 || i + u > h1 || j + v > w1
                        continue;
                    elseif abs(int16(img(i + u, j + v)) - int16(template(half_h + 1 + u, half_w + 1 + v))) < 5
                        cor(i, j) = cor(i, j) + 1;
                    end
                end
            end
            cor(i, j) = exp(cor(i, j) / 8);
        end
    end
    cor = uint8(cor);

(4)调用函数的脚本Task1:

Task1.m

img = imread('car.png');
[h1,w1] = size(img);
template = imread('wheel.png');
[h2,w2] = size(template);

figure();
subplot(2, 2, 1);
imshow(img);
title('Original Image');

subplot(2, 2, 2);
ncorr = NormalizedCorrelation(img, template);
imshow(ncorr);
title('Normalized Correlation Image');

ccorr = CountingCorrelation(img, template);
subplot(2, 2, 3);
imshow(ccorr);
title('Counting Correlation');

correlation = Correlation(img, template);
correlation = correlation / (h2 * w2 * 255);
correlation = uint8(correlation);
subplot(2, 2, 4);
imshow(correlation);
title('Correlation Image');

num = 1;
lightest = zeros(4,2);
for i = 1 : h1
    for j = 1 : w1
        if ccorr(i, j) == 255
            lightest(num,1) = i;
            lightest(num,2) = j;
            num = num + 1;
        end
    end
end

3.处理结果

下图为图像检测效果图对比,

图像检测_第1张图片

检测到的符合的像素点坐标:

图像检测_第2张图片

你可能感兴趣的:(数字图像处理)