2014-06-18 95 views
-1

在找到圖像中的輪廓之後,請考慮我具有輪廓像素和其近似多邊形。如何在OpenCV中旋轉輪廓的像素或輪廓的近似多邊形?

我想旋轉輪廓像素或具有給定角度的近似輪廓多邊形。 OpenCV有可能嗎?

+0

後,你在輪廓的新方向感興趣,或者你要旋轉的那個輪廓的「像素」(例如:內旋轉一個單一的對象圖像和其他應保持不變)? – Micka

+0

是的,我想旋轉輪廓的「像素」。舉例來說:「在圖像中旋轉一個單獨的對象,其餘的應該保持不變」 –

+1

旋轉之前遮擋的像素應該做什麼?我的建議:從輪廓中創建一個填充的蒙版(例如fillpoly函數)。旋轉整個圖像並旋轉蒙版。從旋轉後的圖像中將旋轉後的圖像設置爲原始圖像的像素。要查找旋轉前遮擋的像素,請比較旋轉和未旋轉的蒙版。 – Micka

回答

0

這是你怎麼能像

這是已知的對象/輪廓位置(彩色的東西在那裏)

enter image description here

int main() 
{ 
    cv::Mat input = cv::imread("rotateObjects_input.png"); 

    std::vector<cv::Point> myContour; 
    myContour.push_back(cv::Point(100,100)); 
    myContour.push_back(cv::Point(150,100)); 
    myContour.push_back(cv::Point(150,300)); 
    myContour.push_back(cv::Point(100,300)); 

    cv::Point2f cog(0,0); 
    for(unsigned int i=0; i<myContour.size(); ++i) 
    { 
     cog = cog + cv::Point2f(myContour[i].x, myContour[i].y); 
    } 
    cog = 1.0f/(float)myContour.size()*cog; 

    std::cout << "center of gravity: " << cog << std::endl; 


    // create and draw mask 
    cv::Mat mask = cv::Mat::zeros(input.size(), CV_8UC1); 
    cv::fillConvexPoly(mask,myContour,255); 

    // create rotation mat 
    float angleDEG = 45; 
    cv::Mat transformation = cv::getRotationMatrix2D(cog,angleDEG,1); 
    std::cout << transformation << std::endl; 

    // rotated mask holds the object position after rotation 
    cv::Mat rotatedMask; 
    cv::warpAffine(mask,rotatedMask,transformation,input.size()); 
    cv::Mat rotatedInput; 
    cv::warpAffine(input,rotatedInput,transformation, input.size()); 

    cv::imshow("input",input); 
    cv::imshow("rotated input",rotatedInput); 
    cv::imshow("rotated mask",rotatedMask); 

    // copy rotated object to original image: 
    cv::Mat output = input.clone(); 
    rotatedInput.copyTo(output, rotatedMask); 

    cv::imwrite("rotateObjects_beforeHolefilling.png", output); 

    // now there are pixel left from the old object position. 
    cv::Mat holePixelMask = mask & (255-rotatedMask); 
    // we have to fill those pixel with some kind of background... 
    cv::Mat legalBackground = (255-mask); 
    //cv::erode(legalBackground,) 

    // fill holes. here you could try to find some better background color by averaging in neighborhood or sth. 
    cv::Vec3b lastLegalPixel(0,0,0); 
    for(unsigned int j=0; j<mask.rows; ++j) 
     for(unsigned int i=0; i<mask.cols; ++i) 
     { 
      if(holePixelMask.at<unsigned char>(j,i)) 
      { 
       output.at<cv::Vec3b>(j,i) = lastLegalPixel; 
      } 
      else 
      { 
       if(legalBackground.at<unsigned char>(j,i)) 
        lastLegalPixel = input.at<cv::Vec3b>(j,i); 
      } 
     } 



    cv::imshow("holes before filling", holePixelMask); 
    cv::imshow("legal background", legalBackground); 

    cv::imshow("result", output); 

    cv::waitKey(-1); 
    return 0; 
} 

這是輸入圖像中旋轉對象孔填充前的輸出

enter image description here

這是孔填充

enter image description here

+0

謝謝@Micka。 –