如何在OpenCV中旋转轮廓的像素或轮廓的近似多边形?

时间:2014-06-18 12:53:09

标签: c++ opencv

在图像中找到轮廓后,请考虑我已经轮廓像素和它的近似多边形。

我想用给定的角度旋转轮廓像素或轮廓的近似多边形。是否可以在OpenCV中使用?

1 个答案:

答案 0 :(得分: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