我正在尝试提取草莓图像和容器并使背景变为黑色或白色。我的目标是
- 删除背景 - 使其变黑
- 做精明后跟霍夫找到盒子的矩形
- 为被遮挡的草莓绘制轮廓并计算有多少草莓
我可以部分完成一些任务,但我无法从一开始就完全删除背景。这是到目前为止的图像和我对代码的尝试。
https://www.dropbox.com/s/ypaqlfmert6emki/src.png?dl=0 https://www.dropbox.com/s/zrragdxlg5xfcqe/gray.png?dl=0
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
//#include "opencv2/videoio.hpp"
//#include "opencv2/imgcodecs.hpp"
//#include <opencv2/video.hpp>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
string imageName("");
if (argc != 2) {
printf("Requires 2 arguments - Usage: program_name <image file>\n");
return 0;
}
imageName = argv[1];
printf("image name: %s\n", imageName.c_str());
// variable declarations
Mat src;
Mat image;
Mat imageScaled;
Mat gray_image;
Mat gray_edged;
Mat canny_dst;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Point2f computeIntersect(Vec2f line1, Vec2f line2);
vector<Point2f> lineToPointPair(Vec2f line);
bool acceptLinePair(Vec2f line1, Vec2f line2, float minTheta);
float resize_factor = 1.0; //0.2; //0.75; //0.25; //1.0; //
// load the image, convert it to grayscale, and blur it slightly
src = imread(imageName.c_str(), IMREAD_COLOR); // Read the file
// I am resizing on the original image which is huge.
// If you operate on the image
// pasted here, then you do not need to resize,
// since I am pasting the already resized image
// hence i changed the resize_factor to 1.0 above
resize(src, imageScaled, Size(), resize_factor, resize_factor, INTER_AREA);
cout << "resized original image... " << endl;
namedWindow( "src", WINDOW_AUTOSIZE );
imshow( "src", imageScaled);
waitKey(0);
// convert to grayscale
Mat gray, blurred;
cvtColor( imageScaled, gray, COLOR_BGR2GRAY );
cout << "grayscale image... " << endl;
namedWindow( "grayscale", WINDOW_AUTOSIZE );
imshow( "grayscale", gray);
waitKey(0);
/*
Tried background subtractor (did not work).
I think it would work best with a video frame to isolate
moving object from the static background.
This approach may not work for images.
Ptr<cv::BackgroundSubtractor> bg = createBackgroundSubtractorMOG2(150, 8, false);
bg->apply(gray,fore);
bg->getBackgroundImage(back);
.... Not pasting the code around this, since it did not work for me
*/
//==============================================
// STUCK here
// WANT TO ONLY HAVE THE STRAWBERRIES AND THE CONTAINER
// AND MAKE THE BACKGROUND BLACK.
// HOW DO I DO THIS
//================================================
GaussianBlur( gray, blurred, Size(7,7), 2.0, 2.0 );
cout << "gaussian blur... " << endl;
namedWindow( "gaussian blur", WINDOW_AUTOSIZE );
imshow( "gaussian blur", blurred );
waitKey(0);
// canny detection
Mat edges;
Mat color_dst;
Canny(blurred, edges, 66.0, 133.0, 3);
cvtColor( edges, color_dst, CV_GRAY2BGR );
namedWindow( "canny", WINDOW_AUTOSIZE );
imshow( "canny", edges );
waitKey(0);
/// Find and draw contours
findContours( edges, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
drawContours( gray, contours,-1,cv::Scalar(0,0,255),2);
cout << "contoured image... " << endl;
namedWindow( "contour", WINDOW_AUTOSIZE );
imshow( "contour", gray);
waitKey(0);
vector<Vec2f> lines;
HoughLines( edges, lines, 1, CV_PI/180, 100, 0, 0 );
cout << "Detected " << lines.size() << " lines." << endl;
// draw lines
for( size_t i = 0; i < lines.size(); i++ )
{
float rho = lines[i][0];
float theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
line( color_dst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
}
namedWindow( "lines", WINDOW_AUTOSIZE );
imshow("lines", color_dst);
waitKey(0);
return 0;
}