【OpenCV】使用floodfill()實現PhotoShop魔棒功能
轉自:http://blog.csdn.net/xiaowei_cqu/article/details/8987387
在OpenCV中看到一個很有意思的函式:floodfill()
使用給定顏色填充一個聯通的區域
- C++: int floodFill(InputOutputArray image, Point seedPoint,
- Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(),
- Scalar upDiff=Scalar(), int flags=4 )
C++: int floodFill(InputOutputArray image, Point seedPoint,
Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(),
Scalar upDiff=Scalar(), int flags=4 )
一個簡單的例子:
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <iostream>
- using namespace cv;
- using namespace std;
- //floodfill()
- //Fills a connected component with the given color.
- static void help()
- {
- cout << "\nThis program demonstrated the floodFill() function\n"
- "Call:\n"
- "./ffilldemo [image_name -- Default: fruits.jpg]\n" << endl;
- cout << "Hot keys: \n"
- "\tESC - quit the program\n"
- "\tc - switch color/grayscale mode\n"
- "\tm - switch mask mode\n"
- "\tr - restore the original image\n"
- "\ts - use null-range floodfill\n"
- "\tf - use gradient floodfill with fixed(absolute) range\n"
- "\tg - use gradient floodfill with floating(relative) range\n"
- "\t4 - use 4-connectivity mode\n"
- "\t8 - use 8-connectivity mode\n" << endl;
- }
- Mat image0, image, gray, mask;
- int ffillMode = 1;
- int loDiff = 20, upDiff = 20;
- int connectivity = 4;
- int isColor = true;
- bool useMask = false;
- int newMaskVal = 255;
- static void onMouse( int event, int x, int y, int, void* )
- {
- if( event != CV_EVENT_LBUTTONDOWN )
- return;
- Point seed = Point(x,y);
- int lo = ffillMode == 0 ? 0 : loDiff;
- int up = ffillMode == 0 ? 0 : upDiff;
- int flags = connectivity + (newMaskVal << 8) +
- (ffillMode == 1 ? CV_FLOODFILL_FIXED_RANGE : 0);
- int b = (unsigned)theRNG() & 255;
- int g = (unsigned)theRNG() & 255;
- int r = (unsigned)theRNG() & 255;
- Rect ccomp;
- Scalar newVal = isColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);
- Mat dst = isColor ? image : gray;
- int area;
- if( useMask )
- {
- threshold(mask, mask, 1, 128, CV_THRESH_BINARY);
- area = floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo),
- Scalar(up, up, up), flags);
- imshow( "mask", mask );
- }
- else
- {
- area = floodFill(dst, seed, newVal, &ccomp, Scalar(lo, lo, lo),
- Scalar(up, up, up), flags);
- }
- imshow("image", dst);
- cout << area << " pixels were repainted\n";
- }
- int main( )
- {
- char* filename="0.png";
- image0 = imread(filename, 1);
- if( image0.empty() )
- {
- cout << "Image empty. Usage: ffilldemo <image_name>\n";
- return 0;
- }
- help();
- image0.copyTo(image);
- cvtColor(image0, gray, CV_BGR2GRAY);
- mask.create(image0.rows+2, image0.cols+2, CV_8UC1);
- namedWindow( "image", 0 );
- createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
- createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
- setMouseCallback( "image", onMouse, 0 );
- for(;;)
- {
- imshow("image", isColor ? image : gray);
- int c = waitKey(0);
- if( (c & 255) == 27 )
- {
- cout << "Exiting ...\n";
- break;
- }
- switch( (char)c )
- {
- case 'c':
- if( isColor )
- {
- cout << "Grayscale mode is set\n";
- cvtColor(image0, gray, CV_BGR2GRAY);
- mask = Scalar::all(0);
- isColor = false;
- }
- else
- {
- cout << "Color mode is set\n";
- image0.copyTo(image);
- mask = Scalar::all(0);
- isColor = true;
- }
- break;
- case 'm':
- if( useMask )
- {
- destroyWindow( "mask" );
- useMask = false;
- }
- else
- {
- namedWindow( "mask", 0 );
- mask = Scalar::all(0);
- imshow("mask", mask);
- useMask = true;
- }
- break;
- case 'r':
- cout << "Original image is restored\n";
- image0.copyTo(image);
- cvtColor(image, gray, CV_BGR2GRAY);
- mask = Scalar::all(0);
- break;
- case 's':
- cout << "Simple floodfill mode is set\n";
- ffillMode = 0;
- break;
- case 'f':
- cout << "Fixed Range floodfill mode is set\n";
- ffillMode = 1;
- break;
- case 'g':
- cout << "Gradient (floating range) floodfill mode is set\n";
- ffillMode = 2;
- break;
- case '4':
- cout << "4-connectivity mode is set\n";
- connectivity = 4;
- break;
- case '8':
- cout << "8-connectivity mode is set\n";
- connectivity = 8;
- break;
- }
- }
- return 0;
- }
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
//floodfill()
//Fills a connected component with the given color.
static void help()
{
cout << "\nThis program demonstrated the floodFill() function\n"
"Call:\n"
"./ffilldemo [image_name -- Default: fruits.jpg]\n" << endl;
cout << "Hot keys: \n"
"\tESC - quit the program\n"
"\tc - switch color/grayscale mode\n"
"\tm - switch mask mode\n"
"\tr - restore the original image\n"
"\ts - use null-range floodfill\n"
"\tf - use gradient floodfill with fixed(absolute) range\n"
"\tg - use gradient floodfill with floating(relative) range\n"
"\t4 - use 4-connectivity mode\n"
"\t8 - use 8-connectivity mode\n" << endl;
}
Mat image0, image, gray, mask;
int ffillMode = 1;
int loDiff = 20, upDiff = 20;
int connectivity = 4;
int isColor = true;
bool useMask = false;
int newMaskVal = 255;
static void onMouse( int event, int x, int y, int, void* )
{
if( event != CV_EVENT_LBUTTONDOWN )
return;
Point seed = Point(x,y);
int lo = ffillMode == 0 ? 0 : loDiff;
int up = ffillMode == 0 ? 0 : upDiff;
int flags = connectivity + (newMaskVal << 8) +
(ffillMode == 1 ? CV_FLOODFILL_FIXED_RANGE : 0);
int b = (unsigned)theRNG() & 255;
int g = (unsigned)theRNG() & 255;
int r = (unsigned)theRNG() & 255;
Rect ccomp;
Scalar newVal = isColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);
Mat dst = isColor ? image : gray;
int area;
if( useMask )
{
threshold(mask, mask, 1, 128, CV_THRESH_BINARY);
area = floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo),
Scalar(up, up, up), flags);
imshow( "mask", mask );
}
else
{
area = floodFill(dst, seed, newVal, &ccomp, Scalar(lo, lo, lo),
Scalar(up, up, up), flags);
}
imshow("image", dst);
cout << area << " pixels were repainted\n";
}
int main( )
{
char* filename="0.png";
image0 = imread(filename, 1);
if( image0.empty() )
{
cout << "Image empty. Usage: ffilldemo <image_name>\n";
return 0;
}
help();
image0.copyTo(image);
cvtColor(image0, gray, CV_BGR2GRAY);
mask.create(image0.rows+2, image0.cols+2, CV_8UC1);
namedWindow( "image", 0 );
createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
setMouseCallback( "image", onMouse, 0 );
for(;;)
{
imshow("image", isColor ? image : gray);
int c = waitKey(0);
if( (c & 255) == 27 )
{
cout << "Exiting ...\n";
break;
}
switch( (char)c )
{
case 'c':
if( isColor )
{
cout << "Grayscale mode is set\n";
cvtColor(image0, gray, CV_BGR2GRAY);
mask = Scalar::all(0);
isColor = false;
}
else
{
cout << "Color mode is set\n";
image0.copyTo(image);
mask = Scalar::all(0);
isColor = true;
}
break;
case 'm':
if( useMask )
{
destroyWindow( "mask" );
useMask = false;
}
else
{
namedWindow( "mask", 0 );
mask = Scalar::all(0);
imshow("mask", mask);
useMask = true;
}
break;
case 'r':
cout << "Original image is restored\n";
image0.copyTo(image);
cvtColor(image, gray, CV_BGR2GRAY);
mask = Scalar::all(0);
break;
case 's':
cout << "Simple floodfill mode is set\n";
ffillMode = 0;
break;
case 'f':
cout << "Fixed Range floodfill mode is set\n";
ffillMode = 1;
break;
case 'g':
cout << "Gradient (floating range) floodfill mode is set\n";
ffillMode = 2;
break;
case '4':
cout << "4-connectivity mode is set\n";
connectivity = 4;
break;
case '8':
cout << "8-connectivity mode is set\n";
connectivity = 8;
break;
}
}
return 0;
}
點選圖示改變影象中的連圖區域的顏色:
(轉載請註明作者和出處:http://blog.csdn.net/xiaowei_cqu 未經允許請勿用於商業用途)
相關文章
- photoshop 魔術棒以及反選功能
- Qt加Opencv實現 梯度矯正 功能QTOpenCV梯度
- Photoshop2021一鍵換天空功能如何實現
- python opencv如何實現目標區域裁剪功能PythonOpenCV
- 使用 jQuery 實現分頁功能jQuery
- 使用redis實現互粉功能Redis
- PhotoShop 2022 mac版新增功能Mac
- 常用到的photoshop實用設計功能都在這了!
- Go使用websocket實現彈幕功能GoWeb
- Yii使用DbTarget實現日誌功能
- postgresql使用pgagent來實現job功能SQL
- 如何使用Python 實現秒錶功能?Python
- python OpenCV加法操作的實現PythonOpenCV
- SQL Azure使用Excel實現BI功能:PowerPivotTWSQLExcel
- 使用 iOS OpenGL ES 實現長腿功能iOS
- photoshop使用小技巧
- Mac版 PhotoShop 2021 自動上色功能?Mac
- Android如何實現超級棒的沉浸式體驗Android
- 一起來實現單使用者登入 —— 功能實現
- 使用 HTML5 Canvas 實現簽名功能HTMLCanvas
- springboot整合ElasticSearch使用completion實現補全功能Spring BootElasticsearch
- 使用Spring Boot實現檔案上傳功能Spring Boot
- springboot整合FastDFS使用實現防盜鏈功能Spring BootAST
- Java Web實現使用者登入功能JavaWeb
- 使用java實現希表的基礎功能Java
- 使用IDEA+Maven實現MapReduce的WordCount功能IdeaMaven
- 「Photoshop2021入門教程」新功能——一鍵替換天空使用教程
- 利用MKL實現OpenCV的模板匹配(matchTemplate)OpenCV
- python基於opencv 實現影像時鐘PythonOpenCV
- 紅魔Mars電競手機支援NFC功能嗎?紅魔Mars有沒有NFC功能
- 手把手教你使用LabVIEW OpenCV dnn實現影像分類(含原始碼)ViewOpenCVDNN原始碼
- OpenCV 基本使用OpenCV
- opencv學習(三)——繪圖功能OpenCV繪圖
- Adobe Photoshop 2020 Mac使用教程!如何使用“內容識別填充”功能來刪除內容!Mac
- 如何使用 Vue3 實現文章目錄功能Vue
- mysql使用自定義序列實現row_number功能MySql
- Kubernetes 使用 Ingress-nginx 實現灰度釋出功能Nginx
- SpringBoot整合Redis使用Restful風格實現CRUD功能Spring BootRedisREST
- 使用Redis的有序集合實現排行榜功能Redis