iOSでいくつかの画像処理ツールを開発しています。現在、InputArrayOfArraysタイプの特徴の等高線が計算されています。
宣言:
std::vector<std::vector<cv::Point> > contours_final( temp_contours.size() );
ここで、輪郭で囲まれた元のRGB画像の領域を抽出し、サブ画像をcv::Mat形式としてさらに保存する場合があります。どうやってやるの?
前もって感謝します!
検出された輪郭の領域を抽出するだけでいいのではないかと思います。考えられる解決策は次のとおりです。
using namespace cv;
int main(void)
{
vector<Mat> subregions;
// contours_final is as given above in your code
for (int i = 0; i < contours_final.size(); i++)
{
// Get bounding box for contour
Rect roi = boundingRect(contours_final[i]); // This is a OpenCV function
// Create a mask for each contour to mask out that region from image.
Mat mask = Mat::zeros(image.size(), CV_8UC1);
drawContours(mask, contours_final, i, Scalar(255), CV_FILLED); // This is a OpenCV function
// At this point, mask has value of 255 for pixels within the contour and value of 0 for those not in contour.
// Extract region using mask for region
Mat contourRegion;
Mat imageROI;
image.copyTo(imageROI, mask); // 'image' is the image you used to compute the contours.
contourRegion = imageROI(roi);
// Mat maskROI = mask(roi); // Save this if you want a mask for pixels within the contour in contourRegion.
// Store contourRegion. contourRegion is a rectangular image the size of the bounding rect for the contour
// BUT only pixels within the contour is visible. All other pixels are set to (0,0,0).
subregions.push_back(contourRegion);
}
return 0;
}
透明度をサポートする形式(pngなど)でサブ領域を保存する場合に備えて、オプションでアルファチャネルとして使用するために、個々のマスクを保存することを検討することもできます。
注:各輪郭のバウンディングボックス内のすべてのピクセルを抽出するのではなく、輪郭内のピクセルのみを抽出します。輪郭内ではなくバウンディングボックス内にあるピクセルは0に設定されます。理由は、Matオブジェクトが配列であり、長方形になるためです。
最後に、画像を再作成するために各ピクセルの位置を保存する必要があるため、特別に作成されたデータ構造で輪郭内のピクセルを保存するだけの理由はわかりません。あなたの懸念がスペースを節約することであるならば、それはあなたに多くのスペースを節約することはまったくないでしょう。最もタイトなバウンディングボックスを保存するだけで十分です。代わりに、輪郭領域のピクセルを分析するだけの場合は、輪郭ごとにマスクのコピーを保存して、輪郭内にあるピクセルを確認できるようにします。
cv::approxPolyDP()
ポイントをつなぐ機能を探しています。
この投稿では、手順全体の同様の使用法を共有しました。呼び出しfor
後のループを確認してください。findContours()
あなたが探しているのはcv::boundingRect()だと思います。このようなもの:
using namespace cv;
Mat img = ...;
...
vector<Mat> roiVector;
for(vector<vector<Point> >::iterator it=contours.begin(); it<contours.end(); it++) {
if (boundingRect( (*it)).area()>minArea) {
roiVector.push_back(img(boundingRect(*it)));
}
}
cv :: boundingRect()はPointsのベクトルを取り、cv::Rectを返します。Mat myRoi = img(myRect)を初期化すると、画像のその部分へのポインターが得られます(したがって、myRoiを変更するとimgも変更されます)。
詳しくはこちらをご覧ください。