#include "opencv2/opencv.hpp" using namespace cv; void main() { Mat src = imread("E://bird.jpg"); Rect rect(84, 84, 406, 318);//左上座標(X,Y)和長寬 Mat result, bg, fg; grabCut(src, result, rect, bg, fg, 1, GC_INIT_WITH_RECT); imshow("grab", result); /*threshold(result, result, 2, 255, CV_THRESH_BINARY); imshow("threshold", result);*/ compare(result, GC_PR_FGD, result, CMP_EQ);//result和GC_PR_FGD對應像素相等時,目標圖像該像素值置爲255 imshow("result",result); Mat foreground(src.size(), CV_8UC3, Scalar(255, 255, 255)); src.copyTo(foreground, result);//copyTo有兩種形式,此形式表示result爲mask imshow("foreground", foreground); waitKey(0); }
grab並不是是全黑圖像,對其使用二值化後能看到低像素值的狀況 ios
#include "opencv2/opencv.hpp" using namespace cv; void main() { Mat src = imread("E://bird.jpg"); //Rect rect(84, 84, 406, 318); Rect rect; Mat bgModel, fgModel; Mat result(src.size(), CV_8U, Scalar(0)); Mat ROI(result(Rect(84, 84, 406, 318))); ROI.setTo(GC_PR_FGD);//ROI設置爲多是前景 grabCut(src, result, rect, bgModel, fgModel, 1, GC_INIT_WITH_MASK); //threshold(result, result, 2, 255, CV_THRESH_BINARY); imshow("grab", result); compare(result, GC_PR_FGD, result, CMP_EQ); //result = result&1; imshow("result", result); Mat foreground(src.size(), CV_8UC3, Scalar(255, 255, 255)); src.copyTo(foreground, result); imshow("foreground", foreground); waitKey(0); }
#include "opencv2/opencv.hpp" using namespace cv; void main() { Mat src = imread("E://bird.jpg"); imshow("src", src); Rect rect; //原圖,種子點,新顏色,重繪區域的最小邊界矩形,負差,正差 floodFill(src, Point(20,20), Scalar(255, 0, 0), &rect, Scalar(10, 10, 10), Scalar(10, 10, 10)); imshow("result", src); waitKey(0); }
1 #include "opencv2/opencv.hpp" 2 #include <iostream> 3 using namespace std; 4 using namespace cv; 5 6 Mat g_srcImage, g_dstImage, g_grayImage, g_maskImage;//定義原始圖、目標圖、灰度圖、掩模圖 7 int g_nFillMode = 1;//漫水填充的模式 8 int g_nLowDifference = 20, g_nUpDifference = 20;//負差最大值、正差最大值 9 int g_nConnectivity = 4;//表示floodFill函數標識符低八位的連通值 10 int g_bIsColor = true;//是否爲彩色圖的標識符布爾值 11 bool g_bUseMask = false;//是否顯示掩膜窗口的布爾值 12 int g_nNewMaskVal = 255;//新的從新繪製的像素值 13 14 static void ShowHelpText() 15 { 16 //輸出一些幫助信息 17 printf("\n\n\n\t歡迎來到漫水填充示例程序~\n\n"); 18 printf("\n\n\t按鍵操做說明: \n\n" 19 "\t\t鼠標點擊圖中區域- 進行漫水填充操做\n" 20 "\t\t鍵盤按鍵【ESC】- 退出程序\n" 21 "\t\t鍵盤按鍵【1】- 切換彩色圖/灰度圖模式\n" 22 "\t\t鍵盤按鍵【2】- 顯示/隱藏掩膜窗口\n" 23 "\t\t鍵盤按鍵【3】- 恢復原始圖像\n" 24 "\t\t鍵盤按鍵【4】- 使用空範圍的漫水填充\n" 25 "\t\t鍵盤按鍵【5】- 使用漸變、固定範圍的漫水填充\n" 26 "\t\t鍵盤按鍵【6】- 使用漸變、浮動範圍的漫水填充\n" 27 "\t\t鍵盤按鍵【7】- 操做標誌符的低八位使用4位的鏈接模式\n" 28 "\t\t鍵盤按鍵【8】- 操做標誌符的低八位使用8位的鏈接模式\n" 29 "\n\n\t\t\t\t\t\t\t\t by淺墨\n\n\n" 30 ); 31 } 32 33 //鼠標消息onMouse回調函數 34 static void onMouse(int event, int x, int y, int, void*) 35 { 36 // 若鼠標左鍵沒有按下,便返回 37 if (event != CV_EVENT_LBUTTONDOWN) 38 return; 39 //-------------------【<1>調用floodFill函數以前的參數準備部分】--------------- 40 Point seed = Point(x, y); 41 int LowDifference = (g_nFillMode == 0) ? 0 : g_nLowDifference;//空範圍的漫水填充,此值設爲0,不然設爲全局的g_nLowDifference 42 int UpDifference = g_nFillMode == 0 ? 0 : g_nUpDifference;//空範圍的漫水填充,此值設爲0,不然設爲全局的g_nUpDifference 43 int flags = g_nConnectivity + (g_nNewMaskVal << 8) + 44 (g_nFillMode == 1 ? CV_FLOODFILL_FIXED_RANGE : 0);//標識符的0~7位爲g_nConnectivity,8~15位爲g_nNewMaskVal左移8位的值,16~23位爲CV_FLOODFILL_FIXED_RANGE或者0。 45 46 //隨機生成bgr值 47 int b = (unsigned)theRNG() & 255;//隨機返回一個0~255之間的值 48 int g = (unsigned)theRNG() & 255;//隨機返回一個0~255之間的值 49 int r = (unsigned)theRNG() & 255;//隨機返回一個0~255之間的值 50 Rect ccomp;//定義重繪區域的最小邊界矩形區域 51 52 Scalar newVal = g_bIsColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);//在重繪區域像素的新值,如果彩色圖模式,取Scalar(b, g, r);如果灰度圖模式,取Scalar(r*0.299 + g*0.587 + b*0.114) 53 54 Mat dst = g_bIsColor ? g_dstImage : g_grayImage;//目標圖的賦值 55 int area; 56 57 //--------------------【<2>正式調用floodFill函數】----------------------------- 58 if (g_bUseMask) 59 { 60 threshold(g_maskImage, g_maskImage, 1, 128, CV_THRESH_BINARY); 61 area = floodFill(dst, g_maskImage, seed, newVal, &ccomp, Scalar(LowDifference, LowDifference, LowDifference), 62 Scalar(UpDifference, UpDifference, UpDifference), flags); 63 imshow("mask", g_maskImage); 64 } 65 else 66 { 67 area = floodFill(dst, seed, newVal, &ccomp, Scalar(LowDifference, LowDifference, LowDifference), 68 Scalar(UpDifference, UpDifference, UpDifference), flags); 69 } 70 71 imshow("效果圖", dst); 72 cout << area << " 個像素被重繪\n"; 73 } 74 75 void main() 76 { 77 system("color 2F");//改變console字體顏色 78 g_srcImage = imread("E://lena.jpg", 1);//載入原圖 79 if (!g_srcImage.data) { printf("Oh,no,讀取圖片image0錯誤~! \n"); return; } 80 ShowHelpText(); 81 82 g_srcImage.copyTo(g_dstImage);//拷貝源圖到目標圖 83 //cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);//轉換三通道的image0到灰度圖 84 g_maskImage.create(g_srcImage.rows + 2, g_srcImage.cols + 2, CV_8UC1);//利用image0的尺寸來初始化掩膜mask 85 86 namedWindow("效果圖", CV_WINDOW_NORMAL); 87 //建立Trackbar 88 createTrackbar("負差最大值", "效果圖", &g_nLowDifference, 255, 0); 89 createTrackbar("正差最大值", "效果圖", &g_nUpDifference, 255, 0); 90 //鼠標回調函數 91 setMouseCallback("效果圖", onMouse, 0); 92 93 //循環輪詢按鍵 94 while (1) 95 { 96 //先顯示效果圖 97 imshow("效果圖", g_bIsColor ? g_dstImage : g_grayImage); 98 //獲取鍵盤按鍵 99 int c = waitKey(0); 100 //判斷ESC是否按下,若按下便退出 101 if ((c & 255) == 27) 102 { 103 cout << "程序退出...........\n"; 104 break; 105 } 106 107 //根據按鍵的不一樣,進行各類操做 108 switch ((char)c) 109 { 110 case '1': //若是鍵盤「1」被按下,效果圖在在灰度圖,彩色圖之間互換 111 if (g_bIsColor)//若原來爲彩色,轉爲灰度圖,而且將掩膜mask全部元素設置爲0 112 { 113 cout << "鍵盤「1」被按下,切換彩色/灰度模式,當前操做爲將【彩色模式】切換爲【灰度模式】\n"; 114 cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY); 115 g_maskImage = Scalar::all(0); //將mask全部元素設置爲0 116 g_bIsColor = false; //將標識符置爲false,表示當前圖像不爲彩色,而是灰度 117 } 118 else//若原來爲灰度圖,便將原來的彩圖image0再次拷貝給image,而且將掩膜mask全部元素設置爲0 119 { 120 cout << "鍵盤「1」被按下,切換彩色/灰度模式,當前操做爲將【彩色模式】切換爲【灰度模式】\n"; 121 g_srcImage.copyTo(g_dstImage); 122 g_maskImage = Scalar::all(0); 123 g_bIsColor = true;//將標識符置爲true,表示當前圖像模式爲彩色 124 } 125 break; 126 case '2'://顯示/隱藏掩膜窗口 127 if (g_bUseMask) 128 { 129 destroyWindow("mask"); 130 g_bUseMask = false; 131 } 132 else 133 { 134 namedWindow("mask", 0); 135 g_maskImage = Scalar::all(0); 136 imshow("mask", g_maskImage); 137 g_bUseMask = true; 138 } 139 break; 140 case '3'://恢復原始圖像 141 cout << "按鍵「3」被按下,恢復原始圖像\n"; 142 g_srcImage.copyTo(g_dstImage); 143 cvtColor(g_dstImage, g_grayImage, COLOR_BGR2GRAY); 144 g_maskImage = Scalar::all(0); 145 break; 146 case '4'://使用空範圍的漫水填充 147 cout << "按鍵「4」被按下,使用空範圍的漫水填充\n"; 148 g_nFillMode = 0; 149 break; 150 case '5'://使用漸變、固定範圍的漫水填充 151 cout << "按鍵「5」被按下,使用漸變、固定範圍的漫水填充\n"; 152 g_nFillMode = 1; 153 break; 154 case '6'://使用漸變、浮動範圍的漫水填充 155 cout << "按鍵「6」被按下,使用漸變、浮動範圍的漫水填充\n"; 156 g_nFillMode = 2; 157 break; 158 case '7'://操做標誌符的低八位使用4位的鏈接模式 159 cout << "按鍵「7」被按下,操做標誌符的低八位使用4位的鏈接模式\n"; 160 g_nConnectivity = 4; 161 break; 162 case '8'://操做標誌符的低八位使用8位的鏈接模式 163 cout << "按鍵「8」被按下,操做標誌符的低八位使用8位的鏈接模式\n"; 164 g_nConnectivity = 8; 165 break; 166 } 167 } 168 }