第三節 圖像顏色處理
- 1.顏色比較
- 2.GrabCut分割圖像
- 3.色調、飽和度以及亮度
1.顏色比較
主要實現逐像素的顏色比較,其中注意BGR顏色空間不連續,不利于顏色提取和區分,轉換到Lab空間:
int getColorDistance(const cv::Vec3b& color1, const cv::Vec3b& color2) const {// 方法一return abs(color1[0]-color2[0])+abs(color1[1]-color2[1])+abs(color1[2]-color2[2]);// 方法二return static_cast<int>(cv::norm<int,3>(cv::Vec3i(color[0]-color2[0],color[1]-color2[1],color[2]-color2[2])));// 方法三 直接使用函數cv::Vec3b dist;cv::absdiff(color,color2,dist);return cv::sum(dist)[0];}// 使用指針遍歷圖像進行顏色比較Mat process(const Mat &image) {// same size as input image, but 1-channelresult.create(image.size(),CV_8U);// Converting to Lab color space if (useLab)cv::cvtColor(image, converted, cv::COLOR_BGR2Lab);// get the iteratorsMat_<cv::Vec3b>::const_iterator it= image.begin<Vec3b>();Mat_<cv::Vec3b>::const_iterator itend= image.end<Vec3b>();Mat_<uchar>::iterator itout= result.begin<uchar>();// get the iterators of the converted image if (useLab) {it = converted.begin<cv::Vec3b>();itend = converted.end<cv::Vec3b>();}// 指針遍歷for ( ; it!= itend; ++it, ++itout) {// compute distance from target colorif (getDistanceToTargetColor(*it)<maxDist) {*itout= 255;} else {*itout= 0;}// end of pixel processing ----------------}return result;
}
2.GrabCut分割圖像
floodFill函數,支持用戶選擇種子點,opencv依據差異值進行快速處理,比如office中的設置透明色,就類似于該算法的實現
// testing floodfillcv::floodFill(image, // input/ouput imagecv::Point(100, 50), // seed pointcv::Scalar(255, 255, 255), // repainted color(0,0,0)則是黑色(cv::Rect*)0, // bounding rectangle of the repainted pixel setcv::Scalar(35, 35, 35), // low and high difference thresholdcv::Scalar(35, 35, 35), // most of the time will be identicalcv::FLOODFILL_FIXED_RANGE); // pixels are compared to seed colorcv::namedWindow("Flood Fill result");result = colordetector(image);
GrabCut分割圖像通過用戶標記前景框,算法為2004年提出,主要是將圖像依據顏色相似進行圖塊分割,然后再使用邊緣特征進一步分割,將問題轉化為連通圖的合并問題,最后以四種類型作為結果輸出
// define bounding rectangle cv::Rect rectangle(50,25,210,180);// the models (internally used)cv::Mat bgModel,fgModel; // segmentation resultcv::Mat result; // segmentation (4 possible values)// GrabCut segmentationcv::grabCut(image, // input imageresult, // segmentation resultrectangle,// rectangle containing foreground bgModel, fgModel, // models5, // number of iterationscv::GC_INIT_WITH_RECT); // use rectangle// Get the pixels marked as likely foreground GC_PR_FGD有四種不同分類結果cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);// or:// result= result&1;
兩種方法對比圖下,GrabCut能夠有效保留前景要素邊緣特征
最終基于邊框提取前景要素:
3.色調、飽和度以及亮度
將圖像轉換到連續空間Lab進行處理往往可以獲得更為連續的結果,而HSV顏色表示更加符合人類視覺感知
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
cv::cvtColor(hsv,newImage, cv::COLOR_HSV2BGR);
cv::cvtColor(image,brightness, cv::COLOR_Lab2BGR);void detectHScolor(const cv::Mat& image, // input image double minHue, double maxHue, // Hue interval double minSat, double maxSat, // saturation intervalcv::Mat& mask) { // output mask// convert into HSV spacecv::Mat hsv;cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);// split the 3 channels into 3 imagesstd::vector<cv::Mat> channels;cv::split(hsv, channels);// channels[0] is the Hue// channels[1] is the Saturation// channels[2] is the Value// Hue maskingcv::Mat mask1; // below maxHuecv::threshold(channels[0], mask1, maxHue, 255, cv::THRESH_BINARY_INV);cv::Mat mask2; // over minHuecv::threshold(channels[0], mask2, minHue, 255, cv::THRESH_BINARY);cv::Mat hueMask; // hue maskif (minHue < maxHue)hueMask = mask1 & mask2;else // if interval crosses the zero-degree axishueMask = mask1 | mask2;// Saturation masking// below maxSatcv::threshold(channels[1], mask1, maxSat, 255, cv::THRESH_BINARY_INV);// over minSatcv::threshold(channels[1], mask2, minSat, 255, cv::THRESH_BINARY);cv::Mat satMask; // saturation masksatMask = mask1 & mask2;// combined maskmask = hueMask&satMask;
}
諸如人體皮膚再HSV顏色域中具有顯著的特征
該節相關代碼已上傳到個人文檔,按需下載鏈接: 點擊下載