दिलचस्प पोस्ट
थ्रेडसाफ बनाम फिर से प्रवेश जांचें कि छवि जावास्क्रिप्ट का उपयोग कर सर्वर पर मौजूद है या नहीं? ट्रांसजेन स्पेस बढ़ाएं कौन सा सी ++ मानक पुस्तकालय आवरण कार्य आप उपयोग करते हैं? वर्चुअल फ़ंक्शन को छिपी क्यों मिलता है? onClick मोबाइल (टच) पर काम नहीं कर रहा है मिलिसेकंड को "hh: mm: ss" प्रारूप में कनवर्ट कैसे करें? समान मूल्य के लिए एक सरणी के सभी सदस्यों को कैसे प्रारंभ करें? हमें सस्ती वेब सेवाओं की आवश्यकता क्यों है? OpenMP में "स्थिर" और "गतिशील" शेड्यूल के बीच अंतर क्या है? अजगर का वेबब्रोवर विंडोज 7 पर डिफ़ॉल्ट के बजाय IE को लॉन्च करता है चयन तत्व की सामग्री को सॉर्ट करने के लिए जावास्क्रिप्ट सीएसएस, छवियां, जेएस आईआईएस में नहीं लोड हो रहा है MongoDB एकत्रीकरण: कैसे कुल अभिलेख गणना प्राप्त करने के लिए? Android डिवाइस पर विश्वसनीय सीए प्रमाण पत्र कैसे स्थापित करें?

छवि को घुमाएं और काली सीमाओं को बाहर निकालें

मेरा अनुप्रयोग: मैं एक छवि को घुमाने की कोशिश कर रहा हूं (ओपनसीवी और पायथन का उपयोग कर)

छवियाँ घूर्णन करना

फिलहाल मैंने नीचे कोड विकसित किया है जो इनपुट छवि को घुमाता है, उसे काली सीमाओं के साथ पैड करता है, मुझे ए दे रहा है। मुझे क्या चाहिए B – घुमाए गए छवि के भीतर सबसे बड़ी संभव क्षेत्र की फसल खिड़की। मैं इसे अक्ष अक्षीय गठबंधन बॉक्स को कॉल करता हूं।

यह अनिवार्य रूप से घूमने और फसल के समान है, हालांकि मुझे उस प्रश्न का उत्तर देने के लिए काम नहीं मिल सकता है। इसके अतिरिक्त, यह उत्तर स्पष्ट रूप से केवल वर्ग चित्रों के लिए वैध है। मेरी छवियां आयताकार हैं I

ए को देना कोड:

import cv2 import numpy as np def getTranslationMatrix2d(dx, dy): """ Returns a numpy affine transformation matrix for a 2D translation of (dx, dy) """ return np.matrix([[1, 0, dx], [0, 1, dy], [0, 0, 1]]) def rotateImage(image, angle): """ Rotates the given image about it's centre """ image_size = (image.shape[1], image.shape[0]) image_center = tuple(np.array(image_size) / 2) rot_mat = np.vstack([cv2.getRotationMatrix2D(image_center, angle, 1.0), [0, 0, 1]]) trans_mat = np.identity(3) w2 = image_size[0] * 0.5 h2 = image_size[1] * 0.5 rot_mat_notranslate = np.matrix(rot_mat[0:2, 0:2]) tl = (np.array([-w2, h2]) * rot_mat_notranslate).A[0] tr = (np.array([w2, h2]) * rot_mat_notranslate).A[0] bl = (np.array([-w2, -h2]) * rot_mat_notranslate).A[0] br = (np.array([w2, -h2]) * rot_mat_notranslate).A[0] x_coords = [pt[0] for pt in [tl, tr, bl, br]] x_pos = [x for x in x_coords if x > 0] x_neg = [x for x in x_coords if x < 0] y_coords = [pt[1] for pt in [tl, tr, bl, br]] y_pos = [y for y in y_coords if y > 0] y_neg = [y for y in y_coords if y < 0] right_bound = max(x_pos) left_bound = min(x_neg) top_bound = max(y_pos) bot_bound = min(y_neg) new_w = int(abs(right_bound - left_bound)) new_h = int(abs(top_bound - bot_bound)) new_image_size = (new_w, new_h) new_midx = new_w * 0.5 new_midy = new_h * 0.5 dx = int(new_midx - w2) dy = int(new_midy - h2) trans_mat = getTranslationMatrix2d(dx, dy) affine_mat = (np.matrix(trans_mat) * np.matrix(rot_mat))[0:2, :] result = cv2.warpAffine(image, affine_mat, new_image_size, flags=cv2.INTER_LINEAR) return result 

Solutions Collecting From Web of "छवि को घुमाएं और काली सीमाओं को बाहर निकालें"

इस समाधान / कार्यान्वयन के पीछे गणित समसामयिक प्रश्न के इस समाधान के बराबर है, लेकिन सूत्र सरल हैं और विलक्षणता से बचें। यह अन्य समाधान से सबसे largest_rotated_rect के समान इंटरफ़ेस के साथ अजगर कोड है, लेकिन लगभग सभी मामलों में एक बड़ा क्षेत्र देते हुए (हमेशा सिद्ध इष्टतम):

 def rotatedRectWithMaxArea(w, h, angle): """ Given a rectangle of size wxh that has been rotated by 'angle' (in radians), computes the width and height of the largest possible axis-aligned rectangle (maximal area) within the rotated rectangle. """ if w <= 0 or h <= 0: return 0,0 width_is_longer = w >= h side_long, side_short = (w,h) if width_is_longer else (h,w) # since the solutions for angle, -angle and 180-angle are all the same, # if suffices to look at the first quadrant and the absolute values of sin,cos: sin_a, cos_a = abs(math.sin(angle)), abs(math.cos(angle)) if side_short <= 2.*sin_a*cos_a*side_long: # half constrained case: two crop corners touch the longer side, # the other two corners are on the mid-line parallel to the longer line x = 0.5*side_short wr,hr = (x/sin_a,x/cos_a) if width_is_longer else (x/cos_a,x/sin_a) else: # fully constrained case: crop touches all 4 sides cos_2a = cos_a*cos_a - sin_a*sin_a wr,hr = (w*cos_a - h*sin_a)/cos_2a, (h*cos_a - w*sin_a)/cos_2a return wr,hr 

यहां अन्य समाधान के साथ फ़ंक्शन की तुलना है:

 >>> wl,hl = largest_rotated_rect(1500,500,math.radians(20)) >>> print (wl,hl),', area=',wl*hl (828.2888697391496, 230.61639227890998) , area= 191016.990904 >>> wm,hm = rotatedRectWithMaxArea(1500,500,math.radians(20)) >>> print (wm,hm),', area=',wm*hm (730.9511000407718, 266.044443118978) , area= 194465.478358 

प्रमाण:

दो समानांतर लाइनों के बीच धुरी संरेखित आयत की तलाश करते हुए अधिकतम क्षेत्र है, एक पैरामीटर के साथ एक अनुकूलन समस्या है, जैसे x इस आंकड़े के रूप में: एनिमेटेड पैरामीटर

चलो दो समानांतर रेखाओं के बीच की दूरी को दर्शाते हैं (यह घुमाए गए आयताकार के छोटे पक्ष के रूप में निकलेगा) फिर मां के बाद आयताकारों की a , b x , sx , रिस के साथ एक निरंतर अनुपात है, अर्थात् एक्स = एक पाप α और (एसएक्स) = बी कॉस α:

यहां छवि विवरण दर्ज करें

इसलिए क्षेत्र को अधिकतम करने के लिए a*b मतलब अधिकतम x*(sx) दाहिने कोण वाले त्रिकोण के लिए "ऊँचाई के प्रमेय" के कारण हमें पता है x*(sx) = p*q = h*h अतः अधिकतम क्षेत्र x = sx = s/2 पर पहुंचा है, अर्थात् दो कोनों ई, समानांतर रेखाओं के बीच जी मध्य रेखा पर हैं:

यहां छवि विवरण दर्ज करें

यह समाधान केवल तभी मान्य है यदि यह अधिकतम आयत घुमाए गए आयत में फिट बैठता है इसलिए विकर्ण EG घुमाए गए आयताकार की दूसरी तरफ l से लंबा नहीं होना चाहिए। जबसे

ईजी = एएफटी + डीएच = एस / 2 * (कॉट α + टैन α) = s / (2 * पाप α कॉस α) = s / sin 2 α

हमारे पास हालत है ≤ l sin 2 α, जहां s और l घुमावदार आयताकार के छोटे और लंबे किनारे होते हैं।

एस> एल पाप 2 α के पैरामीटर x छोटा होना चाहिए (s / 2 से) और सभी के किनारों की मांग के बाद आयताकार प्रत्येक घुमाए गए आयताकार के एक किनारे पर होते हैं। यह समीकरण की ओर जाता है

x * खाट α + (एसएक्स) * तन α = l

दे x = पाप α (एल कॉस α – s पाप α) / कॉस 2 α A = x / sin α और b = (sx) / cos α से हम उपर्युक्त फ़ार्मुलों को प्राप्त करते हैं।

इसलिए, कई दावा किए गए समाधानों की जांच करने के बाद, मुझे अंत में एक ऐसी विधि मिली जो काम करती है; एंड्री और मैग्नस हॉफ़ का जवाब एक घुमावदार आयत में सबसे बड़ा आयत की गणना करें ।

नीचे दिए गए पायथन कोड में ब्याज की विधि शामिल है – सबसे largest_rotated_rect – और एक छोटा डेमो

 import math import cv2 import numpy as np def rotate_image(image, angle): """ Rotates an OpenCV 2 / NumPy image about it's centre by the given angle (in degrees). The returned image will be large enough to hold the entire new image, with a black background """ # Get the image size # No that's not an error - NumPy stores image matricies backwards image_size = (image.shape[1], image.shape[0]) image_center = tuple(np.array(image_size) / 2) # Convert the OpenCV 3x2 rotation matrix to 3x3 rot_mat = np.vstack( [cv2.getRotationMatrix2D(image_center, angle, 1.0), [0, 0, 1]] ) rot_mat_notranslate = np.matrix(rot_mat[0:2, 0:2]) # Shorthand for below calcs image_w2 = image_size[0] * 0.5 image_h2 = image_size[1] * 0.5 # Obtain the rotated coordinates of the image corners rotated_coords = [ (np.array([-image_w2, image_h2]) * rot_mat_notranslate).A[0], (np.array([ image_w2, image_h2]) * rot_mat_notranslate).A[0], (np.array([-image_w2, -image_h2]) * rot_mat_notranslate).A[0], (np.array([ image_w2, -image_h2]) * rot_mat_notranslate).A[0] ] # Find the size of the new image x_coords = [pt[0] for pt in rotated_coords] x_pos = [x for x in x_coords if x > 0] x_neg = [x for x in x_coords if x < 0] y_coords = [pt[1] for pt in rotated_coords] y_pos = [y for y in y_coords if y > 0] y_neg = [y for y in y_coords if y < 0] right_bound = max(x_pos) left_bound = min(x_neg) top_bound = max(y_pos) bot_bound = min(y_neg) new_w = int(abs(right_bound - left_bound)) new_h = int(abs(top_bound - bot_bound)) # We require a translation matrix to keep the image centred trans_mat = np.matrix([ [1, 0, int(new_w * 0.5 - image_w2)], [0, 1, int(new_h * 0.5 - image_h2)], [0, 0, 1] ]) # Compute the tranform for the combined rotation and translation affine_mat = (np.matrix(trans_mat) * np.matrix(rot_mat))[0:2, :] # Apply the transform result = cv2.warpAffine( image, affine_mat, (new_w, new_h), flags=cv2.INTER_LINEAR ) return result def largest_rotated_rect(w, h, angle): """ Given a rectangle of size wxh that has been rotated by 'angle' (in radians), computes the width and height of the largest possible axis-aligned rectangle within the rotated rectangle. Original JS code by 'Andri' and Magnus Hoff from Stack Overflow Converted to Python by Aaron Snoswell """ quadrant = int(math.floor(angle / (math.pi / 2))) & 3 sign_alpha = angle if ((quadrant & 1) == 0) else math.pi - angle alpha = (sign_alpha % math.pi + math.pi) % math.pi bb_w = w * math.cos(alpha) + h * math.sin(alpha) bb_h = w * math.sin(alpha) + h * math.cos(alpha) gamma = math.atan2(bb_w, bb_w) if (w < h) else math.atan2(bb_w, bb_w) delta = math.pi - alpha - gamma length = h if (w < h) else w d = length * math.cos(alpha) a = d * math.sin(alpha) / math.sin(delta) y = a * math.cos(gamma) x = y * math.tan(gamma) return ( bb_w - 2 * x, bb_h - 2 * y ) def crop_around_center(image, width, height): """ Given a NumPy / OpenCV 2 image, crops it to the given width and height, around it's centre point """ image_size = (image.shape[1], image.shape[0]) image_center = (int(image_size[0] * 0.5), int(image_size[1] * 0.5)) if(width > image_size[0]): width = image_size[0] if(height > image_size[1]): height = image_size[1] x1 = int(image_center[0] - width * 0.5) x2 = int(image_center[0] + width * 0.5) y1 = int(image_center[1] - height * 0.5) y2 = int(image_center[1] + height * 0.5) return image[y1:y2, x1:x2] def demo(): """ Demos the largest_rotated_rect function """ image = cv2.imread("lenna_rectangle.png") image_height, image_width = image.shape[0:2] cv2.imshow("Original Image", image) print "Press [enter] to begin the demo" print "Press [q] or Escape to quit" key = cv2.waitKey(0) if key == ord("q") or key == 27: exit() for i in np.arange(0, 360, 0.5): image_orig = np.copy(image) image_rotated = rotate_image(image, i) image_rotated_cropped = crop_around_center( image_rotated, *largest_rotated_rect( image_width, image_height, math.radians(i) ) ) key = cv2.waitKey(2) if(key == ord("q") or key == 27): exit() cv2.imshow("Original Image", image_orig) cv2.imshow("Rotated Image", image_rotated) cv2.imshow("Cropped Image", image_rotated_cropped) print "Done" if __name__ == "__main__": demo() 

छवि रोटेशन डेमो

बस इस चित्र को उपरोक्त फाइल के समान निर्देशिका में प्रदर्शित करने के लिए (गैर-स्क्वायर छवियों के साथ काम करता है, प्रदर्शित करने के लिए उभरा हुआ), फिर इसे चलाएं।

महान कार्य के लिए बधाई! मैं सी ++ लाइब्रेरी के साथ ओपनसीवी में अपना कोड इस्तेमाल करना चाहता हूं, इसलिए मैंने इस रूपांतरण का अनुसरण किया। शायद यह दृष्टिकोण अन्य लोगों के लिए सहायक हो सकता है

 #include <iostream> #include <opencv.hpp> #define PI 3.14159265359 using namespace std; double degree_to_radian(double angle) { return angle * PI / 180; } cv::Mat rotate_image (cv::Mat image, double angle) { // Rotates an OpenCV 2 image about its centre by the given angle // (in radians). The returned image will be large enough to hold the entire // new image, with a black background cv::Size image_size = cv::Size(image.rows, image.cols); cv::Point image_center = cv::Point(image_size.height/2, image_size.width/2); // Convert the OpenCV 3x2 matrix to 3x3 cv::Mat rot_mat = cv::getRotationMatrix2D(image_center, angle, 1.0); double row[3] = {0.0, 0.0, 1.0}; cv::Mat new_row = cv::Mat(1, 3, rot_mat.type(), row); rot_mat.push_back(new_row); double slice_mat[2][2] = { {rot_mat.col(0).at<double>(0), rot_mat.col(1).at<double>(0)}, {rot_mat.col(0).at<double>(1), rot_mat.col(1).at<double>(1)} }; cv::Mat rot_mat_nontranslate = cv::Mat(2, 2, rot_mat.type(), slice_mat); double image_w2 = image_size.width * 0.5; double image_h2 = image_size.height * 0.5; // Obtain the rotated coordinates of the image corners std::vector<cv::Mat> rotated_coords; double image_dim_d_1[2] = { -image_h2, image_w2 }; cv::Mat image_dim = cv::Mat(1, 2, rot_mat.type(), image_dim_d_1); rotated_coords.push_back(cv::Mat(image_dim * rot_mat_nontranslate)); double image_dim_d_2[2] = { image_h2, image_w2 }; image_dim = cv::Mat(1, 2, rot_mat.type(), image_dim_d_2); rotated_coords.push_back(cv::Mat(image_dim * rot_mat_nontranslate)); double image_dim_d_3[2] = { -image_h2, -image_w2 }; image_dim = cv::Mat(1, 2, rot_mat.type(), image_dim_d_3); rotated_coords.push_back(cv::Mat(image_dim * rot_mat_nontranslate)); double image_dim_d_4[2] = { image_h2, -image_w2 }; image_dim = cv::Mat(1, 2, rot_mat.type(), image_dim_d_4); rotated_coords.push_back(cv::Mat(image_dim * rot_mat_nontranslate)); // Find the size of the new image vector<double> x_coords, x_pos, x_neg; for (int i = 0; i < rotated_coords.size(); i++) { double pt = rotated_coords[i].col(0).at<double>(0); x_coords.push_back(pt); if (pt > 0) x_pos.push_back(pt); else x_neg.push_back(pt); } vector<double> y_coords, y_pos, y_neg; for (int i = 0; i < rotated_coords.size(); i++) { double pt = rotated_coords[i].col(1).at<double>(0); y_coords.push_back(pt); if (pt > 0) y_pos.push_back(pt); else y_neg.push_back(pt); } double right_bound = *max_element(x_pos.begin(), x_pos.end()); double left_bound = *min_element(x_neg.begin(), x_neg.end()); double top_bound = *max_element(y_pos.begin(), y_pos.end()); double bottom_bound = *min_element(y_neg.begin(), y_neg.end()); int new_w = int(abs(right_bound - left_bound)); int new_h = int(abs(top_bound - bottom_bound)); // We require a translation matrix to keep the image centred double trans_mat[3][3] = { {1, 0, int(new_w * 0.5 - image_w2)}, {0, 1, int(new_h * 0.5 - image_h2)}, {0, 0, 1}, }; // Compute the transform for the combined rotation and translation cv::Mat aux_affine_mat = (cv::Mat(3, 3, rot_mat.type(), trans_mat) * rot_mat); cv::Mat affine_mat = cv::Mat(2, 3, rot_mat.type(), NULL); affine_mat.push_back(aux_affine_mat.row(0)); affine_mat.push_back(aux_affine_mat.row(1)); // Apply the transform cv::Mat output; cv::warpAffine(image, output, affine_mat, cv::Size(new_h, new_w), cv::INTER_LINEAR); return output; } cv::Size largest_rotated_rect(int h, int w, double angle) { // Given a rectangle of size wxh that has been rotated by 'angle' (in // radians), computes the width and height of the largest possible // axis-aligned rectangle within the rotated rectangle. // Original JS code by 'Andri' and Magnus Hoff from Stack Overflow // Converted to Python by Aaron Snoswell (https://stackoverflow.com/questions/16702966/rotate-image-and-crop-out-black-borders) // Converted to C++ by Eliezer Bernart int quadrant = int(floor(angle/(PI/2))) & 3; double sign_alpha = ((quadrant & 1) == 0) ? angle : PI - angle; double alpha = fmod((fmod(sign_alpha, PI) + PI), PI); double bb_w = w * cos(alpha) + h * sin(alpha); double bb_h = w * sin(alpha) + h * cos(alpha); double gamma = w < h ? atan2(bb_w, bb_w) : atan2(bb_h, bb_h); double delta = PI - alpha - gamma; int length = w < h ? h : w; double d = length * cos(alpha); double a = d * sin(alpha) / sin(delta); double y = a * cos(gamma); double x = y * tan(gamma); return cv::Size(bb_w - 2 * x, bb_h - 2 * y); } // for those interested in the actual optimum - contributed by coproc #include <algorithm> cv::Size really_largest_rotated_rect(int h, int w, double angle) { // Given a rectangle of size wxh that has been rotated by 'angle' (in // radians), computes the width and height of the largest possible // axis-aligned rectangle within the rotated rectangle. if (w <= 0 || h <= 0) return cv::Size(0,0); bool width_is_longer = w >= h; int side_long = w, side_short = h; if (!width_is_longer) std::swap(side_long, side_short); // since the solutions for angle, -angle and pi-angle are all the same, // it suffices to look at the first quadrant and the absolute values of sin,cos: double sin_a = fabs(math.sin(angle)), cos_a = fabs(math.cos(angle)); double wr,hr; if (side_short <= 2.*sin_a*cos_a*side_long) { // half constrained case: two crop corners touch the longer side, // the other two corners are on the mid-line parallel to the longer line x = 0.5*side_short; wr = x/sin_a; hr = x/cos_a; if (!width_is_longer) std::swap(wr,hr); } else { // fully constrained case: crop touches all 4 sides double cos_2a = cos_a*cos_a - sin_a*sin_a; wr = (w*cos_a - h*sin_a)/cos_2a; hr = (h*cos_a - w*sin_a)/cos_2a; } return cv::Size(wr,hr); } cv::Mat crop_around_center(cv::Mat image, int height, int width) { // Given a OpenCV 2 image, crops it to the given width and height, // around it's centre point cv::Size image_size = cv::Size(image.rows, image.cols); cv::Point image_center = cv::Point(int(image_size.height * 0.5), int(image_size.width * 0.5)); if (width > image_size.width) width = image_size.width; if (height > image_size.height) height = image_size.height; int x1 = int(image_center.x - width * 0.5); int x2 = int(image_center.x + width * 0.5); int y1 = int(image_center.y - height * 0.5); int y2 = int(image_center.y + height * 0.5); return image(cv::Rect(cv::Point(y1, x1), cv::Point(y2,x2))); } void demo(cv::Mat image) { // Demos the largest_rotated_rect function int image_height = image.rows; int image_width = image.cols; for (float i = 0.0; i < 360.0; i+=0.5) { cv::Mat image_orig = image.clone(); cv::Mat image_rotated = rotate_image(image, i); cv::Size largest_rect = largest_rotated_rect(image_height, image_width, degree_to_radian(i)); // for those who trust math (added by coproc): cv::Size largest_rect2 = really_largest_rotated_rect(image_height, image_width, degree_to_radian(i)); cout << "area1 = " << largest_rect.height * largest_rect.width << endl; cout << "area2 = " << largest_rect2.height * largest_rect2.width << endl; cv::Mat image_rotated_cropped = crop_around_center( image_rotated, largest_rect.height, largest_rect.width ); cv::imshow("Original Image", image_orig); cv::imshow("Rotated Image", image_rotated); cv::imshow("Cropped image", image_rotated_cropped); if (char(cv::waitKey(15)) == 'q') break; } } int main (int argc, char* argv[]) { cv::Mat image = cv::imread(argv[1]); if (image.empty()) { cout << "> The input image was not found." << endl; exit(EXIT_FAILURE); } cout << "Press [s] to begin or restart the demo" << endl; cout << "Press [q] to quit" << endl; while (true) { cv::imshow("Original Image", image); char opt = char(cv::waitKey(0)); switch (opt) { case 's': demo(image); break; case 'q': return EXIT_SUCCESS; default: break; } } return EXIT_SUCCESS; } 

इस मुद्दे की देखभाल करने का एक आसान तरीका है जो पीआईएल नामक एक अन्य मॉड्यूल का उपयोग करता है (यदि आपको ओपनसीवी का उपयोग न करने पर ही उपयोगी हो तो)

नीचे दिया गया कोड बिल्कुल वही है और किसी भी छवि को इस तरह से रोबेट करता है कि आप काले पिक्सल नहीं प्राप्त करेंगे

 from PIL import Image def array_to_img(x, scale=True): x = x.transpose(1, 2, 0) if scale: x += max(-np.min(x), 0) x /= np.max(x) x *= 255 if x.shape[2] == 3: return Image.fromarray(x.astype("uint8"), "RGB") else: return Image.fromarray(x[:,:,0].astype("uint8"), "L") def img_to_array(img): x = np.asarray(img, dtype='float32') if len(x.shape)==3: # RGB: height, width, channel -> channel, height, width x = x.transpose(2, 0, 1) else: # grayscale: height, width -> channel, height, width x = x.reshape((1, x.shape[0], x.shape[1])) return x if __name__ == "__main__": # Calls a function to convert image to array image_array = img_to_array(image_name) # Calls the function to rotate the image by given angle rotated_image = array_to_img(random_rotation(image_array, rotation_angle)) # give the location where you want to store the image rotated_image_name=<location_of_the_image_>+'roarted_image.png' # Saves the image in the mentioned location rotated_image.save(rotated_image_name)