ठीक है, यहाँ एक और संभव समाधान है। मुझे पता है कि आप पायथन के साथ काम करते हैं - मैं सी ++ के साथ काम करता हूं। मैं आपको कुछ विचार दूंगा और उम्मीद है, अगर आप ऐसा चाहते हैं, तो आप इस उत्तर को लागू करने में सक्षम होंगे।
मुख्य विचार पूर्व-प्रसंस्करण का उपयोग नहीं करना है (कम से कम प्रारंभिक चरण में नहीं) और इसके बजाय प्रत्येक लक्ष्य चरित्र पर ध्यान केंद्रित करें, कुछ गुण प्राप्त करें , और इन गुणों के अनुसार प्रत्येक बूँद को फ़िल्टर करें ।
मैं पूर्व-प्रसंस्करण का उपयोग नहीं करने की कोशिश कर रहा हूं क्योंकि: 1) फिल्टर और रूपात्मक चरण बूँद की गुणवत्ता को कम कर सकते हैं और 2) आपका लक्ष्य बूँदें कुछ विशेषताओं को प्रदर्शित करने के लिए प्रकट होती हैं जिनका हम शोषण कर सकते थे, मुख्यतः पहलू अनुपात और क्षेत्र ।
इसे देखें, संख्या और अक्षर सभी व्यापक से अधिक लंबे दिखाई देते हैं ... इसके अलावा, वे एक निश्चित क्षेत्र मूल्य के भीतर भिन्न दिखाई देते हैं। उदाहरण के लिए, आप "बहुत व्यापक" या "बहुत बड़ी" वस्तुओं को छोड़ना चाहते हैं ।
विचार यह है कि मैं वह सब कुछ फ़िल्टर करूँगा जो पूर्व-परिकलित मानों में नहीं आता है। मैंने वर्ण (संख्या और अक्षर) की जांच की और न्यूनतम, अधिकतम क्षेत्र मान और एक न्यूनतम पहलू अनुपात (यहां, ऊंचाई और चौड़ाई के बीच का अनुपात) के साथ आया।
आइए एल्गोरिदम पर काम करते हैं। छवि को पढ़ने से शुरू करें और इसे आधे आयामों तक आकार दें। आपकी छवि वैसे ही बहुत बड़ी है। ग्रेस्केल में बदलें और ओत्सू के माध्यम से एक द्विआधारी छवि प्राप्त करें, यहाँ छद्म कोड में है:
//Read input:
inputImage = imread( "diagram.png" );
//Resize Image;
resizeScale = 0.5;
inputResized = imresize( inputImage, resizeScale );
//Convert to grayscale;
inputGray = rgb2gray( inputResized );
//Get binary image via otsu:
binaryImage = imbinarize( inputGray, "Otsu" );
ठंडा। हम इस छवि के साथ काम करेंगे। आपको हर सफेद बूँद की जांच करने की आवश्यकता है, और एक "गुण फ़िल्टर" लागू करें । मैं प्रत्येक घटक को लूप ट्रूप करने के लिए जुड़े हुए घटकों का उपयोग कर रहा हूं और अपने क्षेत्र और पहलू अनुपात को प्राप्त करता हूं , C ++ में यह निम्नानुसार किया जाता है:
//Prepare the output matrices:
cv::Mat outputLabels, stats, centroids;
int connectivity = 8;
//Run the binary image through connected components:
int numberofComponents = cv::connectedComponentsWithStats( binaryImage, outputLabels, stats, centroids, connectivity );
//Prepare a vector of colors – color the filtered blobs in black
std::vector<cv::Vec3b> colors(numberofComponents+1);
colors[0] = cv::Vec3b( 0, 0, 0 ); // Element 0 is the background, which remains black.
//loop through the detected blobs:
for( int i = 1; i <= numberofComponents; i++ ) {
//get area:
auto blobArea = stats.at<int>(i, cv::CC_STAT_AREA);
//get height, width and compute aspect ratio:
auto blobWidth = stats.at<int>(i, cv::CC_STAT_WIDTH);
auto blobHeight = stats.at<int>(i, cv::CC_STAT_HEIGHT);
float blobAspectRatio = (float)blobHeight/(float)blobWidth;
//Filter your blobs…
};
अब, हम गुण फ़िल्टर लागू करेंगे। यह पूर्व-गणना की गई थ्रेसहोल्ड के साथ तुलना है। मैंने निम्नलिखित मूल्यों का उपयोग किया:
Minimum Area: 40 Maximum Area:400
MinimumAspectRatio: 1
अपने for
लूप के अंदर , इन मूल्यों के साथ वर्तमान बूँद गुणों की तुलना करें। यदि परीक्षण सकारात्मक हैं, तो आप काले रंग को "पेंट" करते हैं। for
लूप के अंदर जारी है :
//Filter your blobs…
//Test the current properties against the thresholds:
bool areaTest = (blobArea > maxArea)||(blobArea < minArea);
bool aspectRatioTest = !(blobAspectRatio > minAspectRatio); //notice we are looking for TALL elements!
//Paint the blob black:
if( areaTest || aspectRatioTest ){
//filtered blobs are colored in black:
colors[i] = cv::Vec3b( 0, 0, 0 );
}else{
//unfiltered blobs are colored in white:
colors[i] = cv::Vec3b( 255, 255, 255 );
}
लूप के बाद, फ़िल्टर की गई छवि का निर्माण करें:
cv::Mat filteredMat = cv::Mat::zeros( binaryImage.size(), CV_8UC3 );
for( int y = 0; y < filteredMat.rows; y++ ){
for( int x = 0; x < filteredMat.cols; x++ )
{
int label = outputLabels.at<int>(y, x);
filteredMat.at<cv::Vec3b>(y, x) = colors[label];
}
}
और बस यही सब है। आपने उन सभी तत्वों को फ़िल्टर किया, जो आप देख रहे हैं, जैसा नहीं है। एल्गोरिथ्म चलाने से आपको यह परिणाम मिलता है:
मैंने अतिरिक्त रूप से परिणामों की बेहतर कल्पना करने के लिए ब्लब्स के बाउंडिंग बॉक्स पाए हैं:
जैसा कि आप देखते हैं, कुछ तत्वों को याद किया जाता है। आप उन गुणों की बेहतर पहचान करने के लिए "गुण फ़िल्टर" को परिष्कृत कर सकते हैं जिन्हें आप देख रहे हैं। एक गहरा समाधान, जिसमें मशीन सीखने का थोड़ा सा समावेश होता है, को एक "आदर्श फीचर वेक्टर" के निर्माण की आवश्यकता होती है, जो कि बूँद से सुविधाओं को निकालता है, और दोनों वैक्टरों की एक समानता माप के माध्यम से तुलना करता है। परिणाम सुधारने के लिए आप कुछ पोस्ट -प्रोसेसर भी लगा सकते हैं ...
जो भी हो, आदमी, आपकी समस्या मामूली नहीं है और न ही आसान मापनीय है, और मैं आपको केवल विचार दे रहा हूं। उम्मीद है, आप अपने समाधान को लागू करने में सक्षम होंगे।