मैं getPerspectiveTransform के पैरामीटर के साथ थोड़ा उलझन में हूं क्योंकि मुझे उचित छवि नहीं दिखाई दे रही है। मेरा कोड यहाँ है। Original_image चर वह छवि है जिसमें स्क्वायर ऑब्जेक्ट (और कुछ अन्य) शामिल हैं जिन्हें मैं फसल करना और एक नई छवि बनाना चाहता हूं (इस Android OpenCV Find Largest Square or Rectangle की तरह कुछ)। चर पी 1, पी 2, पी 3, और पी 4 छवि में सबसे बड़े वर्ग/आयताकार के कोनों के निर्देशांक हैं। पी 1 ऊपरी बाएं है, पी 2 ऊपरी दाएं है, पी 3 निचला दायां है, और पी 4 निचला बायां है (दक्षिणावर्त असाइनिंग)।एंड्रॉइड ओपनसीवी getPerspectiveTransform और warpPerspective
Mat src = new Mat(4,1,CvType.CV_32FC2);
src.put((int)p1.y,(int)p1.x, (int)p2.y,(int)p2.x, (int)p4.y,(int)p4.x, (int)p3.y,(int)p3.x);
Mat dst = new Mat(4,1,CvType.CV_32FC2);
dst.put(0,0, 0,original_image.width(), original_image.height(),original_image.width(), original_image.height(),0);
Mat perspectiveTransform = Imgproc.getPerspectiveTransform(src, dst);
Mat cropped_image = original_image.clone();
Imgproc.warpPerspective(untouched, cropped_image, perspectiveTransform, new Size(512,512));
जब मैं फसलपी_मेज प्रदर्शित करने का प्रयास करता हूं, तो मुझे "मुझे नहीं पता कि यह क्या है" छवि प्राप्त होती है। मुझे लगता है कि getPerspectiveTransform() में मेरे पैरामीटर गलत हैं (या यह है)। कृपया मदद करे। धन्यवाद!
अद्यतन: जब मैंने अपना कोड डीबग किया, तो मुझे पता चला कि मेरे वर्ग/आयताकार के किनारे गलत हैं, कुछ पी 4 को छोड़कर काफी सही हैं। छवि में वर्ग या आयताकार के किनारों का पता लगाने के लिए यह मेरा कोड है। मेरी छवि सबसे बड़ी वर्ग/आयताकार के समोच्च को छोड़कर सभी काले है जिसमें एक सफेद रूपरेखा है।
//we will find the edges of the new_image (corners of the square/rectangle)
Point p1 = new Point(10000, 10000); //upper left; minX && minY
Point p2 = new Point(0, 10000); //upper right; maxX && minY
Point p3 = new Point(0, 0); //lower right; maxX && maxY
Point p4 = new Point(10000, 0); //lower left; minX && maxY
double[] temp_pixel_color;
for (int x=0; x<new_image.rows(); x++) {
for (int y=0; y<new_image.cols(); y++) {
temp_pixel_color = new_image.get(x, y); //we have a black and white image so we only have one color channel
if (temp_pixel_color[0] > 200) { //we found a white pixel
if (x<=p1.x && y<=p1.y) { //for p1, minX && minY
p1.x = x;
p1.y = y;
}
else if (x>=p2.x && y<=p2.y) { //for p2, maxX && minY
p2.x = x;
p2.y = y;
}
else if (x>=p3.x && y>=p3.y) { //for p3, maxX && maxY
p3.x = x;
p3.y = y;
}
else if (x<=(int)p4.x && y>=(int)p4.y) { //for p4, minX && maxY
p4.x = x;
p4.y = y;
}
}
}
}
यहां मेरी नमूना छवि है। रंग हलकों की अनदेखी के रूप में वे के बाद किनारों का पता चलता है तैयार कर रहे हैं:
अद्यतन: 16 जुलाई 2013 मैं कोनों अब अधिकतम 4-उठाई समोच्च का केवल approxCurve का उपयोग कर पता लगा सकते हैं।
private Mat findLargestRectangle(Mat original_image) {
Mat imgSource = original_image;
//Mat untouched = original_image.clone();
//convert the image to black and white
Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);
//convert the image to black and white does (8 bit)
Imgproc.Canny(imgSource, imgSource, 50, 50);
//apply gaussian blur to smoothen lines of dots
Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 5);
//find the contours
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
double maxArea = -1;
int maxAreaIdx = -1;
MatOfPoint temp_contour = contours.get(0); //the largest is at the index 0 for starting point
MatOfPoint2f approxCurve = new MatOfPoint2f();
MatOfPoint2f maxCurve = new MatOfPoint2f();
List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>();
for (int idx = 0; idx < contours.size(); idx++) {
temp_contour = contours.get(idx);
double contourarea = Imgproc.contourArea(temp_contour);
//compare this contour to the previous largest contour found
if (contourarea > maxArea) {
//check if this contour is a square
MatOfPoint2f new_mat = new MatOfPoint2f(temp_contour.toArray());
int contourSize = (int)temp_contour.total();
Imgproc.approxPolyDP(new_mat, approxCurve, contourSize*0.05, true);
if (approxCurve.total() == 4) {
maxCurve = approxCurve;
maxArea = contourarea;
maxAreaIdx = idx;
largest_contours.add(temp_contour);
}
}
}
//create the new image here using the largest detected square
Mat new_image = new Mat(imgSource.size(), CvType.CV_8U); //we will create a new black blank image with the largest contour
Imgproc.cvtColor(new_image, new_image, Imgproc.COLOR_BayerBG2RGB);
Imgproc.drawContours(new_image, contours, maxAreaIdx, new Scalar(255, 255, 255), 1); //will draw the largest square/rectangle
double temp_double[] = maxCurve.get(0, 0);
Point p1 = new Point(temp_double[0], temp_double[1]);
Core.circle(new_image, new Point(p1.x, p1.y), 20, new Scalar(255, 0, 0), 5); //p1 is colored red
String temp_string = "Point 1: (" + p1.x + ", " + p1.y + ")";
temp_double = maxCurve.get(1, 0);
Point p2 = new Point(temp_double[0], temp_double[1]);
Core.circle(new_image, new Point(p2.x, p2.y), 20, new Scalar(0, 255, 0), 5); //p2 is colored green
temp_string += "\nPoint 2: (" + p2.x + ", " + p2.y + ")";
temp_double = maxCurve.get(2, 0);
Point p3 = new Point(temp_double[0], temp_double[1]);
Core.circle(new_image, new Point(p3.x, p3.y), 20, new Scalar(0, 0, 255), 5); //p3 is colored blue
temp_string += "\nPoint 3: (" + p3.x + ", " + p3.y + ")";
temp_double = maxCurve.get(3, 0);
Point p4 = new Point(temp_double[0], temp_double[1]);
Core.circle(new_image, new Point(p4.x, p4.y), 20, new Scalar(0, 255, 255), 5); //p1 is colored violet
temp_string += "\nPoint 4: (" + p4.x + ", " + p4.y + ")";
TextView temp_text = (TextView)findViewById(R.id.temp_text);
temp_text.setText(temp_string);
return new_image;
}
यहाँ नमूना परिणाम छवि है: यहाँ मेरी कोड है
मैं वर्ग/आयत के कोनों के लिए हलकों तैयार की है और मैं भी सभी प्रदर्शित करने के लिए एक TextView जोड़ा चार अंक
ठीक है, मेरे पास समय होने पर मैं आपके कोड पर जाऊंगा, लेकिन तब तक मैं आपको एक सरल दृष्टिकोण बताऊंगा। यदि आप "findContours] (http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours) विधि" CV_CHAIN_APPROX_SIMPLE "के साथ उपयोग करते हैं, तो आप तुरंत कोने पॉइंट प्राप्त कर सकते हैं। – baci
इसके अलावा, वे "किनारों" नहीं हैं, वे "कोनों" हैं :) – baci
क्या आप वाकई "src" और "dst" सही तरीके से बनाए गए हैं? मुझे लगता है कि अगर आप मैट के बजाय "प्वाइंट 2 एफ" सरणी का उपयोग करते हैं तो यह बेहतर होगा। – baci