AnswerOpenCV(0826-0901)一周佳作欣赏

jsxyhelu2015 2018-10-06 05:19:52
1、OpenCV to detect how missing tooth in equipment

Hello everyone. I am just starting with OpenCV and still a bit lost.

Is OpenCV helpful to detect the position of a missing object (tooth for example)?

I would like to build a code to analyze an image of an equipment and detect which tooth is missing and its position.

For example in the image attached below of an equipment that has 9 teeth normally: the code should show a message that the 2nd tooth is missing.

Is this possible with OpenCV? If yes, where do I start?

Attached you will find the figure. missing tooth.PNG


寻找这种类似齿轮的问题,可以在hull距的前提下,进行专门的处理。有兴趣可以继续研究,当然它这个图像质量比较差。

相关函数
convexityDefects
https://docs.opencv.org/master/d3/dc0/group__imgproc__shape.html#gada4437098113fd8683c932e0567f47ba
defects.png

提供教程:https://docs.opencv.org/master/d5/d45/tutorial_py_contours_more_functions.html

2、Detect equipment in desired position

Hello everyone!

Is It possible to evaluate some pictures and save them Just when the object is in some desired position?

For example: monitoring a vídeo of an equipment that moves in and out of the scene. I would like to detect the time when the equipment is fully in the scene and then save It in a desired folder.

Thanks a Lot and have a great weekend

这个问题问的有点不清楚,也可能是非英语为母语的人提出的。实际上他想说明的、寻求的应该是一个MOG问题。

一旦项目由静态的图片提升到了动态的视频,在维度上面就有了提高,因此也会出现许多新的问题。


3、Does findContours create duplicates

Hi,I'm considering a binary image from which I extract its edges using cv::Canny. Consequently, I perform cv::findContours, storing all the contours points coordinates in a

vector < vector < Point > >

I noticed that the number of pixels (Points) in this structure is greater than the number of pixels I get by computing

vector<point> white_pixels;
findNonZero(silhouette, white_pixels);

on the same image.

Therefore I'm wondering if this happens because findContours includes duplicate points in its result or because findNonZero is less precise.

E.g. on a 200x200 sample image with the first method I get 1552 points while with the second I get 877.

In case the first hypothesis is correct, is there a way to either ignore the duplicates or remove them?

非常关键的一题,许多大神给出解答

a、

In case of a Canny edge image findContours will find most of the contour points twice, because the line width is only 1 and findContours is looking for closed contours.

To remove duplicates you can map the contour points to an empty (zero) image.For every contour point add 1 at the image position and only copy the contour point to your new contour vector if the value at this position is zero. That would be the easiest way I think.
flag offensive link
Comments

Thanks! Actually, I did what you suggested using the same sample image and also counting how many pixels were set to 1 (without repetitions). I ended up with having exactly 877 white pixels in the new Mat::zeros image. At this point, i think the result I get by using "findNonZero" is correct, accurate and in this case more efficient since I can avoid the double for loop I used for mapping the contour points for this test.

b、My first answer was wrong. @matman answer is good but I think problem is in blurred image.

If you don't blur enough image you will have many double points. You shape become a line but at beginning your shape could be a rectangle.

if you find double point in your contour may be you have to increase blurring (shape like 8 could be a problem). For fractal shape (or with a large rugosity) it is difficult to delete those points.

In this example I use :surface rectangle 6 (width 3 and height 2)

canny witout blurring Image 0

canny with blur size 3 image 1

Canny with blur size 5 image 2

image description

Source file
{
Mat x = Mat::zeros(20,20,CV_8UC1);
Mat result = Mat::zeros(20,20,CV_8UC3);
vector<Vec3b> c = { Vec3b(255, 0, 0), Vec3b(0,255,0),Vec3b(0,0,255),Vec3b(255, 255, 0),Vec3b(255, 0, 255),Vec3b(0, 255, 255) };
for (int i=9;i<=10;i++)
for (int j = 9; j <= 11; j++)
{
x.at<uchar>(i,j)=255;
result.at<Vec3b>(i,j)=Vec3b(255,255,255);
}
imwrite("square.png",x);
Mat idx;
findNonZero(x,idx);
cout << "Square surface " << idx.rows<<endl;
vector<vector<vector<Point> >> contours(3);
vector<Vec4i> hierarchy;
double thresh=1;
int aperture_size=3;
vector<Mat> xx(3);
vector<Mat> dst(3);
for (size_t i = 0; i < xx.size(); i++)
{
if (i==0)
xx[i]=x.clone();
else
blur(x, xx[i], Size(static_cast<int>(2*i+1),static_cast<int>(2*i+1)));
Canny(xx[i], dst[i],thresh, thresh, 3,true );
namedWindow(format("canny%d",i),WINDOW_NORMAL);
namedWindow(format("result%d",i),WINDOW_NORMAL);
imshow(format("canny%d",i),dst[i]);
findContours(dst[i],contours[i], hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, Point(0, 0));
}

namedWindow("original image",WINDOW_NORMAL);
imshow("original image",x);
/*
Mat dx,dy,g;
Sobel(x, dx, CV_16S, 1, 0, aperture_size, 1, 0, BORDER_REPLICATE);
Sobel(x, dy, CV_16S, 0, 1, aperture_size, 1, 0, BORDER_REPLICATE);
namedWindow("gradient modulus",WINDOW_NORMAL);
g = dx.mul(dx) + dy.mul(dy);
imshow("gradient modulus",g);
findContours(x,contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, Point(0, 0));
cout << "#contours : " << contours.size()<<endl;
if (contours.size() > 0)
{
for (size_t i = 0; i < contours.size(); i++)
{
cout << "#pixel in contour of original image :"<<contours[i].size()<<endl;
for (size_t j=0;j<contours[i].size();j++)
cout << contours[i][j] << "*";
cout<<endl;
drawContours(result, contours, i, c[i]);
}
}*/

size_t maxContour=0;
for (size_t k = 0; k < 3; k++)
{
cout << "#contours("<<k<<") : " << contours[k].size()<<endl;;
if (maxContour<contours[k].size())
maxContour= contours[k].size();
if (contours[k].size() > 0)
{
for (size_t i = 0; i<contours[k].size();i++)
{
cout << "#pixel in contour using canny with original image :"<<contours[i].size()<<endl;
for (size_t j=0;j<contours[k][i].size();j++)
cout << contours[k][i][j] << "*";
cout<<endl;
}

}
else
cout << "No contour found "<<endl;

}
int index=0;
while (true)
{
char key = (char)waitKey();
if( key == 27 )
break;

if (key == '+')
{
index = (index+1)%maxContour;
}
if (key == '-')
{
index = (index-1);
if (index<0)
index = maxContour-1;
}
vector<Mat> result(contours.size());
for (size_t k = 0; k < contours.size(); k++)
{
result[k] = Mat::zeros(20,20,CV_8UC3);
for (int ii=9;ii<=10;ii++)
for (int jj = 9; jj <= 11; jj++)
{
result[k].at<Vec3b>(ii,jj)=Vec3b(255,255,255);
}

if (index<contours[k].size())
drawContours(result[k], contours[k], static_cast<int>(index), c[index]);
else
cout << "No Contour "<<index<<" in image "<<k<<endl;
imshow(format("result%d",k),result[k]);
}
cout << "Contour "<<index<<endl;
}
exit(0);
}

但是对于今天的我来说,分析重复轮廓的意义在哪里了?很多时候,我都只是找最大的外围轮廓就可以的。

4、FindContours Duplicate Points

I am using OpenCV 3.4.1 with VS2015 C++ on a Win10 platform.

My question relates to findContours and whether that should be returning duplicate points within a contour.

For example, I have a test image like this:

image description

I do Canny on it and then I run findContours like this:
findContours(this->MaskFrame,this->Contours,this->Hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);

When I check the resulting contours like this:
for (int x = 0; x < Images->Contours.size(); x++)
for (int y = 0; y < Images->Contours[x].size(); y++)
for (int z = y + 1; z < Images->Contours[x].size(); z++)
if (Images->Contours[x][y] == Images->Contours[x][z])
printf("Contours duplicate point: x: %d, y: %d z: %d\n", x, y, z);

I can see there there are many/hundreds of duplicate points within a given contour.

image description

The presence of the duplicates seems to cause a problem with the drawContours function.
Nevertheless, this image shows that 6 contours were detected with ~19,000 points comprising all the contours, the largest contour has ~18,000 points, but there are 478 points that are duplicated within a contour.

However, this only seems to occur if the total number of points in a given contour is fairly large, e.g., > 2000 points.If I arrange the image so that no contour has more than ~2000 points, as below, then there are no duplicates.

image description

In this image, there are 11 contours, there are ~10,000 points comprising all the contours, with the largest contour having ~1,600 points, and no duplicates.

Before I try and get deep into findContours or something else, I thought I would ask: anyone have any ideas why I am seeing duplicate points within a contour?

Thanks for any help.

这里的具体运用,可能就是问题3的意义所在:通过轮廓分析来获得定量数据。

5、how to find the REAL width and height of contours
这道题目是我问的,而且也给出了最优回答,应该说是有价值的。

there is a image of 3 shapes image description

int main( int argc, char** argv )

{

//read the image

Mat img = imread("e:/sandbox/leaf.jpg");

Mat bw;

bool dRet;

//resize

pyrDown(img,img);

pyrDown(img,img);



cvtColor(img, bw, COLOR_BGR2GRAY);

//morphology operation

threshold(bw, bw, 150, 255, CV_THRESH_BINARY);

//bitwise_not(bw,bw);

//find and draw contours

vector<vector<Point> > contours;

vector<Vec4i> hierarchy;

findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

...全文
215 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

4,247

社区成员

发帖
与我相关
我的任务
社区描述
OpenCV相关技术交流专区
计算机视觉人工智能opencv 技术论坛(原bbs) 广东省·深圳市
社区管理员
  • OpenCV
  • 幻灰龙
  • OpenCV中国团队
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

OpenCV中国团队官方博客:https://blog.csdn.net/opencvchina

试试用AI创作助手写篇文章吧