मैं ब्लॉब पहचान के लिए findContours
का उपयोग करता हूं। अब मैं एक साथ करीबी और समान ब्लॉब्स विलय कर दूंगा।मैं ब्लॉब्स/समोच्चों को कैसे विलय कर सकता हूं
कि सामान्य OpenCV के साथ संभव है:
यहां कुछ ऐसे नमूना छवियों कर रहे हैं?
मैं ब्लॉब पहचान के लिए findContours
का उपयोग करता हूं। अब मैं एक साथ करीबी और समान ब्लॉब्स विलय कर दूंगा।मैं ब्लॉब्स/समोच्चों को कैसे विलय कर सकता हूं
कि सामान्य OpenCV के साथ संभव है:
यहां कुछ ऐसे नमूना छवियों कर रहे हैं?
इनपुट छवियों को आप दे दी हमें सुंदर के साथ काम करने के लिए आसान कर रहे हैं:
पहला कदम सब कुछ से पीले धब्बे को अलग और एक सरल रंग विभाजन तकनीक यह पूरा कर सकते हैं कार्य। आप इसे कैसे करना है इस पर विचार करने के लिए Segmentation & Object Detection by color या Tracking colored objects in OpenCV पर एक नज़र डालें।
फिर, यह धब्बे विलय करने के लिए समय है। विशेष रूप से एक तकनीक जो उपयोगी हो सकती है bounding box, पर सभी ब्लॉब्स को आयताकार के अंदर रखें। नीचे दी गई छवियों में सूचना, एक हरे रंग धब्बे आसपास आयत है कि वहाँ:
उसके बाद, तुम सब करने की जरूरत है अपनी पसंद के रंग के साथ आयत को भरने, इस प्रकार जोड़ने सभी blobs। मैं इसे आपके लिए होमवर्क के रूप में छोड़ रहा हूं।
यह सबसे तेज़ और सबसे आसान तरीका है जिसे मैं सोच सकता हूं। कैसे प्राप्त करने के लिए निम्न कोड को दर्शाया है जिसे मैं सिर्फ वर्णित:
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <vector>
int main(int argc, char* argv[])
{
cv::Mat img = cv::imread(argv[1]);
if (!img.data)
{
std::cout "!!! Failed to open file: " << argv[1] << std::endl;
return 0;
}
// Convert RGB Mat into HSV color space
cv::Mat hsv;
cv::cvtColor(img, hsv, CV_BGR2HSV);
// Split HSV Mat into HSV components
std::vector<cv::Mat> v;
cv::split(hsv,v);
// Erase pixels with low saturation
int min_sat = 70;
cv::threshold(v[1], v[1], min_sat, 255, cv::THRESH_BINARY);
/* Work with the saturated image from now on */
// Erode could provide some enhancement, but I'm not sure.
// cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
// cv::erode(v[1], v[1], element);
// Store the set of points in the image before assembling the bounding box
std::vector<cv::Point> points;
cv::Mat_<uchar>::iterator it = v[1].begin<uchar>();
cv::Mat_<uchar>::iterator end = v[1].end<uchar>();
for (; it != end; ++it)
{
if (*it) points.push_back(it.pos());
}
// Compute minimal bounding box
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
// Display bounding box on the original image
cv::Point2f vertices[4];
box.points(vertices);
for (int i = 0; i < 4; ++i)
{
cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 1, CV_AA);
}
cv::imshow("box", img);
//cv::imwrite(argv[2], img);
cvWaitKey(0);
return 0;
}
thx ... लेकिन आपने मुझे थोड़ा सा गलत समझा। पीले रंग के blobs वास्तव में पीले रंग नहीं हैं।मैंने उन्हें आपको चुड़ैल ब्लब्स दिखाने के लिए रंग दिया है, मैं विलय करने की कोशिश करूंगा। इसलिए मैं अन्य ब्लॉब्स को अलग करने के लिए रंग विभाजन का उपयोग करने में सक्षम नहीं हूं। क्षेत्र की तरह जानकारी भी काम नहीं करेगी क्योंकि शायद कुछ अन्य बड़े ब्लॉब्स चुड़ैल हैं जो मैं विलय करना पसंद नहीं करता ... – rouge
बह! = \ बाद में कुछ और के बारे में सोचना होगा। – karlphillip
आप सबसे बड़े ब्लॉब्स में रुचि रखते हैं, है ना? – karlphillip
मुझे लगता है कि मैं यह किया, धन्यवाद अपने कार्यक्रम विवरण के लिए मैं इस समाधान पाया: (टिप्पणियों का स्वागत है)
vector<vector<Point> > contours;
vector<vector<Point> > tmp_contours;
findContours(detectedImg, tmp_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
vector<vector<Point> >::iterator it1;
it1 = tmp_contours.begin();
Mat test;
test = Mat(FImage.size(), CV_32FC3);
while (it1 != tmp_contours.end()) {
vector<Point> approx1;
approxPolyDP(Mat(*it1), approx1, 3, true);
Rect box1 = boundingRect(approx1);
float area1 = contourArea(approx1);
if ((area1 > 50) && (area1 < 13000) && (box1.width < 100) && (box1.height < 120)) {
vector<vector<Point> >::iterator it2;
it2 = tmp_contours.begin();
while (it2 != tmp_contours.end()) {
vector<Point> approx2;
approxPolyDP(Mat(*it2), approx2, 3, true);
Moments m1 = moments(Mat(approx1), false);
Moments m2 = moments(Mat(approx2), false);
float x1 = m1.m10/m1.m00;
float y1 = m1.m01/m1.m00;
float x2 = m2.m10/m2.m00;
float y2 = m2.m01/m2.m00;
vector<Point> dist;
dist.push_back(Point(x1, y1));
dist.push_back(Point(x2, y2));
float d = arcLength(dist, false);
Rect box2 = boundingRect(approx2);
if (box1 != box2) {
if (d < 25) {
//Method to merge the vectors
approx1 = mergePoints(approx1, approx2);
}
}
++it2;
}
Rect b = boundingRect(approx1);
rectangle(test, b, CV_RGB(125, 255, 0), 2);
contours.push_back(approx1);
}
++it1;
}
आप पोस्ट कर सकते हैं एक नमूना छवि? – karlphillip
बेहतर अगर आप एक छवि जोड़ते हैं। Imageshack.us में अपलोड करें और यहां लिंक दें। यह भी निर्दिष्ट करें कि आप इसी तरह से क्या मतलब है। क्या यह आकार में समान है? या समान क्षेत्र है? आदि –
ठीक है, मैं एक दूसरे के बगल में समान आकार मर्ज करना चाहता हूं। यहां तीन उदाहरण हैं (पीले रंग के रूप में चिह्नित करें) सहायता के लिए धन्यवाद! [छवि 1] (http://img713.imageshack.us/img713/2152/image1xg.png) [छवि 2] (http://img32.imageshack.us/img32/2149/image2kl.png) [छवि 3] (http://img256.imageshack.us/img256/1000/image3jg.png) – rouge