2015-02-17 11 views
8

[500x500] कहने के लिए किसी भी आकार या आकार की छवियों का आकार बदलने का कोई तरीका है, लेकिन छवि के पहलू अनुपात को बनाए रखा जा सकता है, खाली स्थान को सफेद/काला भराव से भरा जाना चाहिए ?एक स्क्वायर पर एक छवि का आकार बदलें, लेकिन पहलू अनुपात सी ++ ओपनसीवी

तो कहते हैं कि छवि [2000x1000] है, सफेद/काला भराव किया जा रहा है [500x500] का आकार बदला हो रही बनाने वास्तविक छवि को ही [500x250] होगा, 125 साथ दोनों ओर के बाद।

कुछ इस तरह:

इनपुट

enter image description here

आउटपुट

enter image description here

संपादित

मैं बस एक स्क्वायर विंडो में छवि को प्रदर्शित नहीं करना चाहता, बल्कि छवि को उस स्थिति में बदल दिया गया है और फिर उसी छवि छवियों का संग्रह बनाने के लिए सहेजा गया है, जितना संभव हो उतना छोटी छवि विकृति के साथ।

एकमात्र प्रश्न जो मैं एक समान प्रश्न पूछने आया था this post था, लेकिन इसकी php थी।

+3

आप की कोशिश की * कुछ भी *: क्षैतिज बॉर्डर न जोड़ें जब छवि को क्षैतिज फिट बैठता है (यह मूल अनुरोध के करीब है)? –

+0

मैं छवियों का आकार बदल सकता हूं, ब्लैक के अतिरिक्त जो मुझे – MLMLTL

+1

के बारे में नहीं पता है, अपनी पृष्ठभूमि को काले रंग से भरें, फिर उस पर छवि पेस्ट करें ...? –

उत्तर

10

पूरी तरह से अनुकूल नहीं है, लेकिन आप यह कोशिश कर सकते हैं:

संपादित संभाल लक्ष्य आकार कि 500x500 पिक्सल नहीं है और एक समारोह के रूप में यह ऊपर लपेटकर।

cv::Mat GetSquareImage(const cv::Mat& img, int target_width = 500) 
{ 
    int width = img.cols, 
     height = img.rows; 

    cv::Mat square = cv::Mat::zeros(target_width, target_width, img.type()); 

    int max_dim = (width >= height) ? width : height; 
    float scale = ((float) target_width)/max_dim; 
    cv::Rect roi; 
    if (width >= height) 
    { 
     roi.width = target_width; 
     roi.x = 0; 
     roi.height = height * scale; 
     roi.y = (target_width - roi.height)/2; 
    } 
    else 
    { 
     roi.y = 0; 
     roi.height = target_width; 
     roi.width = width * scale; 
     roi.x = (target_width - roi.width)/2; 
    } 

    cv::resize(img, square(roi), roi.size()); 

    return square; 
} 
+0

मैंने कुछ चीजें बदल दीं ताकि नई छवि हर बार 500x500 फिट करने के लिए फैली न हो, लेकिन असल में आकार क्या सेट है, लेकिन अन्यथा, हाँ महान! – MLMLTL

+0

संपादन के साथ, यह बिल्कुल सही – MLMLTL

+1

महान, धन्यवाद, बीटीडब्ल्यू, आप पैरामीटर के साथ पृष्ठभूमि रंग को भी नियंत्रित कर सकते हैं, लेकिन मैंने चीजों को सरल रखा .. –

1

आप अपनी इच्छित स्क्वायर आकार की एक और छवि बना सकते हैं, फिर अपनी छवि को स्क्वायर छवि के बीच में रखें। कुछ इस तरह:

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include "opencv2/imgproc/imgproc.hpp" 

int main(int argc, char *argv[]) 
{ 
    // read an image 
    cv::Mat image1= cv::imread("/home/hdang/Desktop/colorCode.png"); 

    //resize it 
    cv::Size newSize = cv::Size(image1.cols/2,image1.rows/2); 
    cv::resize(image1, image1, newSize, 0, 0, cv::INTER_LINEAR); 

    //create the square container 
    int dstWidth = 500; 
    int dstHeight = 500; 
    cv::Mat dst = cv::Mat(dstHeight, dstWidth, CV_8UC3, cv::Scalar(0,0,0)); 

    //Put the image into the container, roi is the new position 
    cv::Rect roi(cv::Rect(0,dst.rows*0.25,image1.cols,image1.rows)); 
    cv::Mat targetROI = dst(roi); 
    image1.copyTo(targetROI); 

    //View the result 
    cv::namedWindow("OpenCV Window"); 
    cv::imshow("OpenCV Window", dst); 

    // wait key for 5000 ms 
    cv::waitKey(5000); 

    return 0; 
} 
5

एक सामान्य दृष्टिकोण:

cv::Mat utilites::resizeKeepAspectRatio(const cv::Mat &input, const cv::Size &dstSize, const cv::Scalar &bgcolor) 
{ 
    cv::Mat output; 

    double h1 = dstSize.width * (input.rows/(double)input.cols); 
    double w2 = dstSize.height * (input.cols/(double)input.rows); 
    if(h1 <= dstSize.height) { 
     cv::resize(input, output, cv::Size(dstSize.width, h1)); 
    } else { 
     cv::resize(input, output, cv::Size(w2, dstSize.height)); 
    } 

    int top = (dstSize.height-output.rows)/2; 
    int down = (dstSize.height-output.rows+1)/2; 
    int left = (dstSize.width - output.cols)/2; 
    int right = (dstSize.width - output.cols+1)/2; 

    cv::copyMakeBorder(output, output, top, down, left, right, cv::BORDER_CONSTANT, bgcolor); 

    return output; 
} 
4

एलिरेज़ा का जवाब अच्छा है, लेकिन मैं कोड जब छवि खड़ी है और मैं फिट बैठता है थोड़ा ताकि मैं लंबवत बॉर्डर न जोड़ें संशोधित

cv::Mat utilites::resizeKeepAspectRatio(const cv::Mat &input, const cv::Size &dstSize, const cv::Scalar &bgcolor) 
{ 
    cv::Mat output; 

    // initially no borders 
    int top = 0; 
    int down = 0; 
    int left = 0; 
    int right = 0; 
    if(h1 <= dstSize.height) 
    { 
     // only vertical borders 
     top = (dstSize.height - h1)/2; 
     down = top; 
     cv::resize(input, output, cv::Size(dstSize.width, h1)); 
    } 
    else 
    { 
     // only horizontal borders 
     left = (dstSize.width - w2)/2; 
     right = left; 
     cv::resize(input, output, cv::Size(w2, dstSize.height)); 
    } 

    return output; 
} 
+0

आपका समाधान अधूरा है और यह स्पष्ट नहीं है कि कैसे Alireza के कोड को संशोधित किया जाना चाहिए आपका अपना। – apk

+0

समाधान को और अधिक पूर्ण करने के लिए अपडेट किया गया –

संबंधित मुद्दे