วิธีที่ดีกว่าในการสร้างมาสก์สี่เหลี่ยมโดย openCV

การสร้างมาสก์ใน openCV

      /** result I want
          0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0
          0 0 1 1 1 1 0 0
          0 0 1 1 1 1 0 0
          0 0 1 1 1 1 0 0
          0 0 1 1 1 1 0 0
          0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0
      */    
cv::Mat mask = cv::Mat::zeros(8, 8, CV_8U);
std::cout<<"before : \n"<<mask<<std::endl;
for(int i = 2; i != 6; ++i)
{
     auto ptr = mask.ptr<uchar>(i) + 2;
     for(int j = 0; j != 4; ++j)
     {
         *ptr++ = 1;
     }
}
std::cout<<"after : \n"<<mask<<std::endl;   

openCV มีฟังก์ชัน build in ให้เราสร้างมาสก์แบบนี้หรือไม่ การสร้างฟังก์ชันสำหรับงานนี้ไม่ใช่เรื่องเล็กน้อย แต่ฟังก์ชันของ openCV จะเร็วกว่าโค้ดที่ทำด้วยมือแบบไร้เดียงสาเสมอ


person StereoMatching    schedule 08.08.2013    source แหล่งที่มา


คำตอบ (2)


แน่นอนว่ามีวิธีที่ง่ายกว่านี้ ใช้ตัวดำเนินการ roi:

cv::Mat mask = cv::Mat::zeros(8, 8, CV_8U); // all 0
mask(Rect(2,2,4,4)) = 1;

เสร็จแล้ว!

person berak    schedule 08.08.2013
comment
สำหรับผู้ที่ต้องการแสดงภาพมาสก์ ควรตั้งค่าเป็น 255 แทน 1 โดยให้มาสก์ใช้เป็นบูลีนมาสก์เท่านั้น - person zanbri; 11.04.2017

หากใครกำลังมองหาการสร้างมาสก์ที่ไม่ใช่สี่เหลี่ยมแล้วนำไปใช้กับภาพ ลองดูที่นี่ :

Mat& obtainIregularROI(Mat& origImag, Point2f topLeft, Point2f topRight, Point2f botLeft, Point2f botRight){

        static Mat black(origImag.rows, origImag.cols, origImag.type(), cv::Scalar::all(0));
        Mat mask(origImag.rows, origImag.cols, CV_8UC1, cv::Scalar(0));
        vector< vector<Point> >  co_ordinates;
        co_ordinates.push_back(vector<Point>());
        co_ordinates[0].push_back(topLeft);
        co_ordinates[0].push_back(botLeft);
        co_ordinates[0].push_back(botRight);
        co_ordinates[0].push_back(topRight);
        drawContours( mask,co_ordinates,0, Scalar(255),CV_FILLED, 8 );

        origImag.copyTo(black,mask);
        return black;
    }

"สีดำ" คือภาพที่ในที่สุดเราก็จะได้ผลลัพธ์โดยการครอบตัด ROI ที่ผิดปกติออกจากภาพต้นฉบับ

 static Mat black(origImag.rows, origImag.cols, origImag.type(), cv::Scalar::all(0));

"mask" คือ Mat ซึ่งเตรียมใช้งานเป็นขนาดเดียวกับรูปภาพต้นฉบับและเต็มไปด้วย 0 Mat mask(origImag.rows, origImag.cols, CV_8UC1, cv::Scalar(0));

วางพิกัดในทิศทาง ANTICLOCKWISE

    vector< vector<Point> >  co_ordinates;
    co_ordinates.push_back(vector<Point>());
    co_ordinates[0].push_back(topLeft);
    co_ordinates[0].push_back(botLeft);
    co_ordinates[0].push_back(botRight);
    co_ordinates[0].push_back(topRight);

ตอนนี้กำลังสร้างหน้ากากขึ้นมาจริงๆ

drawContours( mask,co_ordinates,0, Scalar(255),CV_FILLED, 8 );

ในตอนท้าย ให้คัดลอกส่วนที่มาสก์/ROI จากรูปภาพต้นฉบับ (origImag) และวางส่วนของ ROI จากรูปภาพต้นฉบับ (โดยใช้มาสก์) ลงในรูปภาพที่มีชื่อว่า "สีดำ"

origImag.copyTo(black,mask);
person Spandan    schedule 24.12.2017