Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过检测图像中的特定大对象或斑点来裁剪图像?_C++_Matlab_Opencv_Image Processing - Fatal编程技术网

C++ 通过检测图像中的特定大对象或斑点来裁剪图像?

C++ 通过检测图像中的特定大对象或斑点来裁剪图像?,c++,matlab,opencv,image-processing,C++,Matlab,Opencv,Image Processing,请任何人帮助我解决我的问题。我正在从事一个基于图像处理的项目,我在某一点上陷入了困境。经过一些处理后,我得到了这张图像,为了进一步处理,我只需要裁剪或检测鹿,并删除图像的其他部分 这是我最初的图像: 我的结果应该是这样的: 如果我只在图像中获得一个最大的斑点并将其保存为图像,效果会更好。看起来您图像中的鹿几乎是连接和闭合的。我们可以使用regionprops查找图像中的所有边界框。一旦我们这样做,我们就可以找到边界框,它给出了最大的区域,大概就是你的鹿。一旦我们找到这个边界框,我们就可以裁剪

请任何人帮助我解决我的问题。我正在从事一个基于图像处理的项目,我在某一点上陷入了困境。经过一些处理后,我得到了这张图像,为了进一步处理,我只需要裁剪或检测鹿,并删除图像的其他部分

这是我最初的图像:

我的结果应该是这样的:


如果我只在图像中获得一个最大的斑点并将其保存为图像,效果会更好。

看起来您图像中的鹿几乎是连接和闭合的。我们可以使用
regionprops
查找图像中的所有边界框。一旦我们这样做,我们就可以找到边界框,它给出了最大的区域,大概就是你的鹿。一旦我们找到这个边界框,我们就可以裁剪您的图像并将焦点完全集中在鹿身上。因此,假设您的图像存储在
im
中,请执行以下操作:

im = im2bw(im); %// Just in case...
bound = regionprops(im, 'BoundingBox', 'Area'); 

%// Obtaining Bounding Box co-ordinates
bboxes = reshape([bound.BoundingBox], 4, []).';

%// Obtain the areas within each bounding box
areas = [bound.Area].';

%// Figure out which bounding box has the maximum area
[~,maxInd] = max(areas);

%// Obtain this bounding box
%// Ensure all floating point is removed
finalBB = floor(bboxes(maxInd,:));

%// Crop the image
out = im(finalBB(2):finalBB(2)+finalBB(4), finalBB(1):finalBB(1)+finalBB(3));

%// Show the images
figure;
subplot(1,2,1);
imshow(im);
subplot(1,2,2);
imshow(out);
让我们慢慢地看一下这段代码。为了以防万一,我们首先将图像转换为二进制。您的图像可能是强度为0或255的RGB图像。。。我不能肯定,所以让我们做一个二进制转换以防万一。然后,我们使用
BoundingBox
属性调用
regionprops
,以查找图像中每个唯一对象的每个边界框。此边界框是最小跨度边界框,以确保对象包含在其中。每个边界框是一个4元素数组,其结构如下:

[x y w h]
每个边界框由其位于框左上角的原点划定,表示为
x
y
,其中
x
为水平坐标,
y
为垂直坐标
x
从左到右递增,而
y
从上到下递增
w,h
是边界框的宽度和高度。因为这些点位于一个结构中,所以我提取它们并将它们放入一个一维向量中,然后对其进行重塑,使其成为一个
mx4
矩阵。请记住,这是我所知道的唯一一种方法,它可以有效地为每个结构元素提取数组中的值,而无需任何
for
循环。这将有助于我们更快地搜索。对于
区域
属性,我也做了同样的操作。对于图像中的每个边界框,我们还具有封装在边界框中的总面积属性

多亏了@Shai,我们不能简单地使用边界框坐标来确定某个物体是否有最大的面积,因为我们可以有一条细对角线来驱动边界框坐标更高。因此,我们还需要依赖对象在边界框中占据的总面积。简单地说,它只是对象中包含的所有像素的总和

因此,我们搜索已创建的整个面积向量,以查看哪个面积最大。这对应于你的鹿。找到该位置后,提取边界框位置,然后使用该位置裁剪图像。请记住,边界框值可能有浮点数。由于图像坐标是基于整数的,我们需要在决定裁剪之前删除这些浮点值。我决定使用
地板
。然后,我编写代码来显示原始图像以及裁剪后的结果

请记住,只有当图像中只有一个对象时,才起作用。如果要查找多个对象,请在MATLAB中进行检查。否则,我相信这会让你开始

为了完整起见,我们得到以下结果:


虽然目标检测是一项非常普通的CV任务,但如果假设足够充分,并且可以保证输入图像将包含一个由边界框很好描述的突出白色斑点,则可以从简单的任务开始

一个非常简单的想法是将图片细分为3x3=9个面片,计算每个面片的统计信息并计算一些目标函数。在最简单的情况下,您只需在各个分区上进行网格搜索,并选择具有最高目标度量的分区。下面是一个例子:

如果每一行都是一个参数x_1、x_2、y_1和y_2,那么您需要进行优化

或者

  • (在一些量化步骤中尝试所有x_i、y_i)
  • -像随机搜索
  • (沿优化目标函数的方向移动每个参数)
目标函数F可以定义补丁的统计信息,例如

F(9 patches) {
  brightest_patch = max(patches)
  others          = patches \ brightest_patch
  score           = brightness(brightest_patch) - 1/8 * brightness(others)
  return score
}

或者任何包含补丁及其大小的相关统计信息的内容。这也允许引入一个“先验知识”:如果你期望BLUB出现在图像的中间,那么你可以定义一个“正则化”项,如果参数XII和YYI过多偏离了预期位置,就会惩罚F。在你的帮助下,我得到了确切的答案。我正在为其他人发布我的最终代码和结果

img = im2bw(imread('deer.png'));
[L, num] = bwlabel(img, 4);

 %%//  Get biggest blob or object
count_pixels_per_obj = sum(bsxfun(@eq,L(:),1:num));
[~,ind] = max(count_pixels_per_obj);
biggest_blob = (L==ind);

%%// crop only deer
bound = regionprops(biggest_blob, 'BoundingBox');

%// Obtaining Bounding Box co-ordinates
bboxes = reshape([bound.BoundingBox], 4, []).';

%// Obtain this bounding box
%// Ensure all floating point is removed
finalBB = floor(bboxes);
out = biggest_blob(finalBB(2):finalBB(2)+finalBB(4),finalBB(1):finalBB(1)+finalBB(3));

%%// Show images
figure;
imshow(out);

使用解决方案并使用最小/最大x-y坐标裁剪出来。我很想对“请尽快回答我”这句话投反对票@LuisMendo猜想我把他救到那里了:)我会很好,我会写一个答案->一个腔:你根据BB面积而不是实际面积来选择区域。想象一条细对角线-BB面积非常大,而实际面积非常小。。。您可以考虑使用<代码>区域> /COD>属性来选择该区域。@ SHIA-编辑完成。不费吹灰之力。感谢您的点评。使用已知尺寸的整形乘积4时出错,不能划分为元素总数1530。@rayryeng您能检查一下我的原始图像,然后编译吗。