由於須要,以前寫了一個利用mask 獲得不規則ROI 區域的程序。
如今須要修改,發現本身都看不懂是怎麼作的了。。
因此把它整理下來。函數
首先利用 鼠標能夠獲得 你想要的不規則區域的 頂點信息。具體這裏再也不描述。
setMouseCallback("setROIParking_Image", on_MouseHandle, (void*)&SrcImage);
獲得不規則區域的頂點以後以後,接下來生成mask.
具體程序以下.net
void Image::GetROImage() { Mat srcImage = imread(srcImageName); for (int j = 0; j < ROInumber; j++) { Point root_points[1][4]; root_points[0][0] = DrawPoints[j*4]; root_points[0][1] = DrawPoints[j*4 + 1]; root_points[0][2] = DrawPoints[j*4 + 2]; root_points[0][3] = DrawPoints[j*4 + 3]; const Point* ppt[1] = { root_points[0] }; int npt[] = { 4 }; // polylines(srcImage, ppt, npt, 1, 1, Scalar(0, 0, 0), 1, 8, 0); vector <Mat>mv; cv::Mat mask_ann, dst,dst1,dst2; srcImage.copyTo(mask_ann); mask_ann.setTo(cv::Scalar::all(0)); fillPoly(mask_ann, ppt, npt, 1, Scalar(255, 255, 255)); split(mask_ann, mv); srcImage.copyTo(dst, mv[0]); vector<Point> rectPoints = {}; //獲得rectangle 的角點 rectPoints.push_back(DrawPoints[j * 4]); rectPoints.push_back(DrawPoints[j * 4 +1]); rectPoints.push_back(DrawPoints[j * 4 +2]); rectPoints.push_back(DrawPoints[j * 4 +3]); Rect rec = boundingRect(Mat(rectPoints)); dst1 = dst(rec); //boundingRect(Mat(rectPoints)) //獲得rectROImage if (dst1.cols >= 160) { resize(dst1, dst2, Size(160, 120),0,0,3); //獲得rectROImage_resize //降採樣 } else { resize(dst1, dst2, Size(160, 120),0,0,1);//放大 } //默認爲線性插值 INTER_NEAREST = 0(最近鄰插值), //INTER_LINEAR = 1(線性插值,默認值), //INTER_CUBIC = 2(三次樣條插值),INTER_AREA = 3(區域插值);INTER_LANCZOS4 = 4(Lanczos插值), //INTER_MAX = 7, WARP_FILL_OUTLIERS = 8, //降採樣:3, 放大:2(效率不高,不推薦);1(效率高,推薦) imwrite(ROImageNames[j], dst); imwrite(rectROImageNames[j], dst1); imwrite(rectROImageNames_resize[j], dst2); imwrite(rectROImageNames_resize_[j], dst2); } }
我這裏寫的可能有些冗餘,主要本身有點的也不是太懂,就根據本身的須要一點點添加獲得本身想要的效果。code
其中,DrawPoints裏存儲了不規則區域的頂點(我這裏設定了是不規則四邊形)。首先是 生成mask(我這裏是mask_ann),blog
srcImage.copyTo(mask_ann); mask_ann.setTo(cv::Scalar::all(0));
這一部分是生成和原圖同樣大小的mask 圖像,而後將整個圖像用黑色填充。圖片
const Point* ppt[1] = { root_points[0] }; int npt[] = { 4 }; fillPoly(mask_ann, ppt, npt, 1, Scalar(255, 255, 255));
這一部分是在mask 圖像中將不規則區域的部分用白色填充,參考:http://blog.csdn.net/billbliss/article/details/43968291 能夠看一下效果get
vector <Mat>mv; split(mask_ann, mv); srcImage.copyTo(dst, mv[0]);
我添加的這一部分代碼,是跟通道分離有關,具體 也不是特別清楚。可是在我沒有添加這一句時,最後獲得的圖像 有問題(會獲得一個不規則ROI區域,可是不是本身想要的那一部分)。split 函數是將mask_ann的三個通道分別賦值給 mv . 由於這裏的 mask_ann 是三通道的,並且三通道應該是同樣的,咱們後面利用mask獲得想要的不規則區域時只用到的他的一個通道。mv[0] 即它的一個通道。it
後面的class
srcImage.copyTo(dst, mv[0]);
即獲得想要的不規則區域。即除了不規則區域,其餘區域所有爲黑色。效率
Rect rec = boundingRect(Mat(rectPoints)); dst1 = dst(rec); //boundingRect(Mat(rectPoints)) //獲得rectROImage
是我從上面獲得的部分中進一步的裁剪,把多餘的黑色去掉,提取出了以 ROI 區域爲邊界的的圖片(規則四邊形,周圍區域用黑色填充,由於若是ROI區域過小,獲得的圖片中大部分都是黑色,因此進一步裁剪)。程序
由於我想獲得最終 尺寸同樣的圖像,因此利用resize進行了 升降採樣。