首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于内容的图像检索与精确召回图在MATLAB中的应用

基于内容的图像检索与精确召回图在MATLAB中的应用
EN

Stack Overflow用户
提问于 2014-09-14 04:57:45
回答 1查看 1.6K关注 0票数 3

到目前为止,我已经能够在CBIR系统中绘制灰度图像的精确回忆图.但是,我想知道如何对RGB图像执行相同的处理。

我的代码:

代码语言:javascript
复制
Inp1=rgb2gray(imread('D:\visionImages\c1\1.ppm'));
figure, imshow(Inp1), title('Input image 1');
num_bins = 32;
A = imhist(Inp1, num_bins);
srcFiles = dir('D:\visionImages\c1\*.ppm');  
B = zeros(num_bins, 30); 
ptr=1;
for i = 1 : length(srcFiles)
    filename = strcat('D:\visionImages\c1\',srcFiles(i).name);
    I = imread(filename);
    I=rgb2gray(I);
    B(:,ptr) = imhist(I, num_bins); 
    ptr=ptr+1;                                                      
end

% histogram intersection
a = size(A,2); b = size(B,2); 
K = zeros(a, b);
for i = 1:a
  Va = repmat(A(:,i),1,b);
  K(i,:) = 0.5*sum(Va + B - abs(Va - B));
end

num_images = 30;
sims=K
relevant_IDs = [1 2 3 4 5 6 7 8 9 10];
num_relevant_images = numel(relevant_IDs);
[sorted_sims, locs] = sort(sims, 'descend');
locations_final = arrayfun(@(x) find(locs == x, 1), relevant_IDs)
locations_sorted = sort(locations_final)
precision = (1:num_relevant_images) ./ locations_sorted;
recall = (1:num_relevant_images) / num_relevant_images;
plot(recall, precision, 'b.-');
xlabel('Recall');
ylabel('Precision');
title('Precision-Recall Graph');
axis([0 1 0 1.05]); 
grid;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-14 06:55:51

您编写的代码是比较图像之间的直方图,前提是它们是灰度的。如果要对RGB图像执行此操作,则需要确定每架飞机需要多少个回收箱。一旦你这样做,对于每个RGB颜色三重奏,你会确定一个线性的一维指数,这样这将实质上是一个正常的一维直方图。一旦您这样做,您可以使用上面的代码以与上面指定的相同的方式。因此,让我们创建一个接受图像的函数imcolourhist,以及您想要的红色、绿色和蓝色回收箱的总数。请记住,不能为每个维度指定256个桶。这不仅是粒度太细,没有任何区分能力,而且您将需要2^24 = 16777216内存位置,而MATLAB肯定会给您一个内存不足的错误。

一般的程序是确定每种颜色都属于哪一种颜色。这样做之后,您将创建一个线性的一维索引,它本质上是一个一维直方图的bin,然后在该位置增加该值。我将使用accumarray为我计算直方图。一旦完成,这将基本上取代您的imhist调用,您将在这个直方图上执行直方图交集,这个直方图是从imcolourhist输出的。

代码语言:javascript
复制
function [out] = imcolourhist(im, num_red_bins, num_green_bins, num_blue_bins)

    im = double(im); %// To maintain precision

    %// Compute total number of bins
    total_bins = num_red_bins*num_green_bins*num_blue_bins;

    %// Figure out threshold between bins
    red_level = 256 / num_red_bins;
    green_level = 256 / num_green_bins;
    blue_level = 256 / num_blue_bins;

    %// Calculate which bins for each colour plane
    %// each pixel belongs to
    im_red_levels = floor(im(:,:,1) / red_level);
    im_green_levels = floor(im(:,:,2) / green_level);
    im_blue_levels = floor(im(:,:,3) / blue_level);

    %// Compute linear indices
    ind = im_blue_levels*num_red_bins*num_green_bins + im_green_levels*num_red_bins + im_red_levels;
    ind = ind(:); %// Make column vector for accumarray

    %// Determine 1D histogram - Ensure that every histogram
    %// generated has the same size of total_bins x 1
    out = accumarray(ind+1, 1, [total_bins 1]);
end

将这段代码复制并粘贴到一个新文件中,然后将其保存为imcolourhist.m。请确保将此代码保存在与上面显示的代码所在的目录相同的位置。请注意,在accumarray中,我将线性索引抵消1,因为我生成的线性索引将从0开始,但是MATLAB在1开始索引。现在,您所要做的就是将imhist调用替换为imcolourhist。我建议你选择每个彩色频道的回收箱为8(即num_red_bins = num_green_bins = num_blue_bins = 8 )。为了取得好的结果,你必须玩这个游戏。

因此,您可以将正在计算A直方图的代码更改为:

代码语言:javascript
复制
Inp1=imread('D:\visionImages\c1\1.ppm');  
num_red_bins = 8;
num_green_bins = 8;
num_blue_bins = 8;
num_bins = num_red_bins*num_green_bins*num_blue_bins;
A = imcolourhist(Inp1, num_red_bins, num_green_bins, num_blue_bins);

请注意,我在图像中读取的是颜色,因此删除了rgb2gray调用。同样,对于B,您可以这样做:

代码语言:javascript
复制
B = zeros(num_bins, 30); 
ptr=1;
for i = 1 : length(srcFiles)
    filename = strcat('D:\visionImages\c1\',srcFiles(i).name);
    I = imread(filename);
    B(:,ptr) = imcolourhist(I, num_red_bins, num_green_bins, num_blue_bins); 
    ptr=ptr+1;                                                      
end

请注意,我不能保证在这里取得好的结果。因为您只使用颜色直方图作为图像检索的方法,所以您可以有一个查询图像和一个数据库图像,它们可能具有相同的颜色分布,但是在纹理和组成方面看起来完全不同。如果这两幅图像的颜色分布是相同的,那么它们就会被认为是高度相似的,尽管它们看起来根本不像对方。

祝好运!

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25830225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档