使用OpenCV(Android)如何计算一堆物体的数量?

huangapple go评论72阅读模式
英文:

How to Count a Stack of Object using OpenCV ( Android )?

问题

I can help you with the translation. Here's the translated content:

我有这张图片,想要计算图片中有多少张卡片,如何使用OpenCV进行计数?我已经尝试过,但始终只返回一张卡片。

原始图片(来自相机):

![enter image description here](https://i.stack.imgur.com/OB70T.png)

灰度化+阈值处理后的图片:

![enter image description here](https://i.stack.imgur.com/3ExB5.png)

我的代码:

```java
Imgproc.cvtColor(srcMat, gray2, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(gray2,thresh,165,255,THRESH_BINARY);

Imgproc.HoughLinesP(thresh, lines, 1.0, Math.PI / 180, 50, 100.0, 10.0);
double num_lines = lines.cols();

for(int j =0; j <= lines.rows(); j++){
    if(lines.get(j,0) != null){
        double [] dArr = lines.get(j,0);
        Point point1 = new Point(dArr[0],dArr[1]);
        Point point2 = new Point(dArr[2],dArr[3]);
        Imgproc.line(
                thresh,
                point1,
                point2,
                new Scalar(0.0, 255.0, 0.0),
                1
        );
    }
}

我已经尝试过形态学变换和Canny边缘检测,但结果导致图像破裂:

使用OpenCV(Android)如何计算一堆物体的数量?

是否有可能计数这种细长的物体?我要计数的真实对象更细。

谢谢帮助!(对不起,我的英语不太好)

我希望有人能纠正我的代码/给我一个解决方法。


Please note that I've translated the code comments and text within the code as well. If you have any specific questions or need further assistance, feel free to ask.

<details>
<summary>英文:</summary>

I have this image and want to count how many card on this image , how to count using openCV ? im already try but its always return only one
original image ( from camera )
[![enter image description here](https://i.stack.imgur.com/OB70T.png)](https://i.stack.imgur.com/OB70T.png)


after graying + threshold



[![enter image description here](https://i.stack.imgur.com/3ExB5.png)](https://i.stack.imgur.com/3ExB5.png)

my code

Imgproc.cvtColor(srcMat, gray2, Imgproc.COLOR_BGR2GRAY);
//Imgproc.threshold(gray2, ada, 0, 255, Imgproc.THRESH_OTSU);
Imgproc.threshold(gray2,thresh,165,255,THRESH_BINARY);

        Imgproc.HoughLinesP(thresh, lines, 1.0, Math.PI / 180, 50, 100.0, 10.0);
        double num_lines = lines.cols();

        for(int j =0; j &lt;= lines.rows();j++){
            if(lines.get(j,0) != null){
                double [] dArr = lines.get(j,0);
                Point point1 = new Point(dArr[0],dArr[1]);
                Point point2 = new Point(dArr[2],dArr[3]);
                Imgproc.line(
                        thresh,
                        point1,
                        point2,
                        new Scalar(0.0, 255.0, 0.0),
                        1
                );
            }
        }

im already trying to morph and canny but the result make image broke

[![enter image description here](https://i.stack.imgur.com/NfK5m.png)](https://i.stack.imgur.com/NfK5m.png)

are possible to count that object because it so thin ? and the real object i want to count is more thinner.

thanks for the help ! ( sorry for bad english )

i want someone can correct my code / give me a good code how to solve that

</details>


# 答案1
**得分**: 1

我尝试了一下。

然而...
我认为你必须首先提取兴趣区域(卡片部分),但我不知道如何做,因为这可能强烈依赖于目标图像的一些隐含先决条件(卡片位置、背景颜色等)。

因此,在这里,我的尝试是从已提取的区域图像开始的。
下面的图是我尝试的截图,包括4张图像。

* 最上面的图像是提取的区域图像(这是我的尝试的输入,手工剪裁的)。
* 第二张二值化图像是OpenCV的`adaptiveThreshold`的结果。对于真实场景,获得理想的二值化结果通常非常困难/不切实际。因此,正如你所看到的,这个结果也不是“理想的”(所有卡片没有完美分离)。
* 第三张图显示了对第二张图像进行`connectedComponentsWithStats`的结果。我为每个标记的区域绘制了红线,以表示x位置和宽度(一些非常小的区域被忽略了)。

到目前为止,大多数区域的宽度似乎是卡片宽度的很好表示。
所以,我从这个结果估计了卡片的宽度。
我所做的非常简单:

1. 计算宽度值的平均值。
2. 删除与平均值非常不同的宽度值。
3. 如果至少有一个值被删除,则返回步骤1。否则,当前的平均值是估计结果。

最后,我重新计算了卡片的数量。
对于每个区域,我将区域宽度除以估计的卡片宽度。
截图中的第四张图是结果。我为每个估计的卡片位置绘制了绿线。
重新计数的结果是`26`。

希望这篇帖子对你有一点帮助。

<details>
<summary>英文:</summary>

I tried a little.

However...  
I think you must extract interest region (Card part) at first, but I don&#39;t know how to, because it may strongly depend on some implicit prior condition about target image (where the cards, background color, etc).

So, here, **my try was started from already extracted region image**.  
The figure below is screenshot of my try, including 4 images.

[![enter image description here][1]][1]

* Top most image is the extracted region image (this is input for my try. cut outed by hand.)
* The 2nd binalized image is result of OpenCV&#39;s `adaptiveThreshold`. Obtaining ideal binalization result is often very difficult/unrealistic for real scene. So, this result is also not &quot;ideal&quot;, as you see (All cards don&#39;t be separated perfectly).
* The 3rd shows result of `connectedComponentsWithStats` to the 2nd. I drew red lines for each labeled region to represent x-location and width. (some very small regions were ignored)

At this point, it seems that width of most regions is a good representation of the width of the card.
So, I estimated card width from this result.  
What I did is very simple :

1. Calculate average of width values.
2. Remove width values which very differ from the average.
3. Go back to 1. if at least one value removed. Else, current average value is estimation result.

Then, finally, I re-counted the number of cards.
Just divided region width by estimated card width, for each region.  
The 4th image in screenshot is the result. I drew green lines for each estimated card location.  
Re-count result becomes to `26`.

I hope this post can be a bit of help to you.


  [1]: https://i.stack.imgur.com/bdPGg.png

</details>



huangapple
  • 本文由 发表于 2023年5月26日 01:06:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76334725.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定