Noodles package detection using opencv


To improve the robustness and application area of the algorithm, we further improve the algorithm.

Possible problems we may encounter are:

Shape of target is not rectangle

Dirty marks or obstacles

Incomplete shape of targets

Partly connected with other objects


Focusing on these problems, we improved the algorithm by adding double contour detection, adjusting optimal threshold and so on.

blob.png

blob.png

blob.png


blob.png

code:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

/**************Definitons*************/
#define MAXRECT				100
#define BUF_SIZE			256
#define CLIENT_ADDRESS		"10.220.12.109"
#define LISTEN_PORT			2000
#define ID					"50-0503334900"
#define THRESH				15
#define AREALIMIT			3000.0
/**************Variables**************/

vector<RotatedRect>		rectProfile;
vector< vector<Point> >	contoursRect;
vector< vector<Point> >	contours;
vector<int> selected;
char buf[BUF_SIZE];
/**************Functions**************/

bool Check(vector<Point> con){
	double area = abs(contourArea(con, 1));
	printf("%lf\n", area);
	if (area < AREALIMIT) 
		return false;
	return true;
}


void ImageProcess(){
	Mat img = imread("total.jpg", CV_LOAD_IMAGE_GRAYSCALE);//sample00012_5.BMP
	Mat imgCanny;
	Canny(img, imgCanny, THRESH, THRESH * 3);
	imshow("imgCanny", imgCanny);
	imwrite("1.ImageCanny.jpg",imgCanny);

	//dilate and erode to connect seperate contour lines
	Mat img_dilate,img_erode;
	dilate ( imgCanny, img_dilate, Mat());
	imshow("Imagedilate", img_dilate);
	imwrite("2.Imagedilate.jpg",img_dilate);
	erode ( img_dilate, img_erode, Mat());
	imshow("Imageerode", img_erode);
	imwrite("3.Imageerode.jpg",img_erode);
	img_dilate.release();
	
	waitKey();

	findContours(img_erode, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
	img_erode.release();
	Mat cc = Mat::zeros(imgCanny.rows, imgCanny.cols, CV_8UC3);
	for (int j = 0; j < contours.size(); j++){
		Scalar color(rand()&255, rand()&255, rand()&255);
		drawContours(cc, contours, j, color);
	}
	imshow("ImageContours", cc);
	imwrite("4.ImageContours.jpg",cc);
	cc.release();
	int n = 0;
	contoursRect.clear();
	for (unsigned int i = 0; i < contours.size(); i++){
		//check size
		if (Check(contours[i])){
			contoursRect.push_back(contours[i]);
			n++;
			selected.push_back(i);
		}
	}
	printf("%d\n", n);

	Mat ccc = Mat::zeros(imgCanny.rows, imgCanny.cols, CV_8UC3);
	for (int i = 0; i < n; i++){
		Scalar color(rand()&255, rand()&255, rand()&255);
		drawContours(ccc, contoursRect, i, color,CV_FILLED);
	}
	imshow("ImageRecQualified", ccc);
	imwrite("5.ImageRecSizeQualified.jpg",ccc);
	waitKey();
	

	destroyAllWindows();
	rectProfile.clear();

	//MORPH_OPEN to seperate connected rect
	Mat minrect= Mat::zeros(imgCanny.rows, imgCanny.cols, CV_8UC3);
	Mat element = getStructuringElement(MORPH_ELLIPSE, Size(28,28)); 
	morphologyEx(ccc,minrect,MORPH_OPEN,element);
	imshow("MORPH_OPEN", minrect);
	imwrite("6.ImageMORPH_OPEN.jpg",minrect);
	ccc.release();
	waitKey();

	//find contour again
	Mat minrectgrey=Mat::zeros(imgCanny.rows, imgCanny.cols, CV_8UC1);;
	cvtColor(minrect,minrectgrey,CV_BGR2GRAY);
	Mat imgCanny2= Mat::zeros(imgCanny.rows, imgCanny.cols, CV_8UC1);;
	Canny(minrectgrey, imgCanny2,  1,10);
	imshow("imgCanny2", imgCanny2);
	imwrite("7.ImageCanny2.jpg",imgCanny2);
	
	contours.clear();
	findContours(imgCanny2, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

	n = 0;
	contoursRect.clear();
	for (unsigned int i = 0; i < contours.size(); i++){
		if (Check(contours[i])){
			contoursRect.push_back(contours[i]);
			n++;
			selected.push_back(i);
		}
	}
	printf("%d\n", n);

	Mat ccc2 = Mat::zeros(imgCanny.rows, imgCanny.cols, CV_8UC3);
	for (int i = 0; i < n; i++){
		Scalar color(rand()&255, rand()&255, rand()&255);
		drawContours(ccc2, contoursRect, i, color,CV_FILLED);
	}
	imshow("ImageRecQualified2", ccc2);
	imwrite("8.ImageRecQualified2.jpg",ccc2);
	waitKey();

	img = imread("total.jpg");
	Point2f vertices[4];
	for (int i = 0; i < n; i++) {
		rectProfile.push_back(minAreaRect(contoursRect[i]));
		rectProfile[i].points(vertices);
		Scalar color(rand()&255, rand()&255, rand()&255);
		for (int i = 0; i < 4; i++){
			line(img, vertices[i], vertices[(i+1)%4], color,5);
		}
		rectangle(img,Point((vertices[0].x+vertices[2].x)/2-1,(vertices[0].y+vertices[2].y)/2-1),Point((vertices[0].x+vertices[2].x)/2+1,(vertices[0].y+vertices[2].y)/2+1),color,5);
	}
	imshow("ImageRec", img);
	imwrite("9.ImageRec.jpg",img);
	waitKey();
}


int main(){
	contours.reserve(100000*sizeof(Point));
	ImageProcess();
}


This article is among the series of FDUROP project. More information: http://104.131.150.53/thinkcmfx/index.php?g=&m=article&a=index&id=17

Last Article Next article

Comment 评论



Share 分享

New Users 最新加入

  • hokurikustr

  • refrain

New comments 最新评论

test123: aasdas Details Apr 13 16:39
admin: Thanks! Details Apr 09 11:46
admin: Google map api Details Apr 09 11:46
lqj12: cooooooooool Details Apr 08 21:34
Yunhan Huang: 这个功能是如何实现的? Details Apr 08 13:23