OpenCV中文网站

 找回密码
 立即注册
搜索
热搜: 安装 配置
12
返回列表 发新帖
楼主: kakaweek

我想使用opencv识别并自动截取一张照片上的蓝色部分?现...

[复制链接]
发表于 2014-4-3 23:04:24 | 显示全部楼层
apigisfly 发表于 2014-4-3 17:41
我也在做类似的工作,在线的程序怎么看到呢?没有显示啊

貌似有人昨天把我的帖子删了,我再补上吧。



#include <sstream>
#include <string>
#include <iostream>
#include <opencv\highgui.h>
#include <opencv\cv.h>

using namespace cv;
//initial min and max HSV filter values.
//these will be changed using trackbars
int H_MIN = 0;
int H_MAX = 256;
int S_MIN = 0;
int S_MAX = 256;
int V_MIN = 0;
int V_MAX = 256;
//default capture width and height
const int FRAME_WIDTH = 640;
const int FRAME_HEIGHT = 480;
//max number of objects to be detected in frame
const int MAX_NUM_OBJECTS=50;
//minimum and maximum object area
const int MIN_OBJECT_AREA = 20*20;
const int MAX_OBJECT_AREA = FRAME_HEIGHT*FRAME_WIDTH/1.5;
//names that will appear at the top of each window
const string windowName = "Original Image";
const string windowName1 = "HSV Image";
const string windowName2 = "Thresholded Image";
const string windowName3 = "After Morphological Operations";
const string trackbarWindowName = "Trackbars";
void on_trackbar( int, void* )
{//This function gets called whenever a
        // trackbar position is changed





}
string intToString(int number){


        std::stringstream ss;
        ss << number;
        return ss.str();
}
void createTrackbars(){
        //create window for trackbars


        namedWindow(trackbarWindowName,0);
        //create memory to store trackbar name on window
        char TrackbarName[50];
        sprintf( TrackbarName, "H_MIN", H_MIN);
        sprintf( TrackbarName, "H_MAX", H_MAX);
        sprintf( TrackbarName, "S_MIN", S_MIN);
        sprintf( TrackbarName, "S_MAX", S_MAX);
        sprintf( TrackbarName, "V_MIN", V_MIN);
        sprintf( TrackbarName, "V_MAX", V_MAX);
        //create trackbars and insert them into window
        //3 parameters are: the address of the variable that is changing when the trackbar is moved(eg.H_LOW),
        //the max value the trackbar can move (eg. H_HIGH),
        //and the function that is called whenever the trackbar is moved(eg. on_trackbar)
        //                                  ---->    ---->     ---->      
        createTrackbar( "H_MIN", trackbarWindowName, &H_MIN, H_MAX, on_trackbar );
        createTrackbar( "H_MAX", trackbarWindowName, &H_MAX, H_MAX, on_trackbar );
        createTrackbar( "S_MIN", trackbarWindowName, &S_MIN, S_MAX, on_trackbar );
        createTrackbar( "S_MAX", trackbarWindowName, &S_MAX, S_MAX, on_trackbar );
        createTrackbar( "V_MIN", trackbarWindowName, &V_MIN, V_MAX, on_trackbar );
        createTrackbar( "V_MAX", trackbarWindowName, &V_MAX, V_MAX, on_trackbar );


}
void drawObject(int x, int y,Mat &frame){

        //use some of the openCV drawing functions to draw crosshairs
        //on your tracked image!

        //UPDATE:JUNE 18TH, 2013
        //added 'if' and 'else' statements to prevent
        //memory errors from writing off the screen (ie. (-25,-25) is not within the window!)

        circle(frame,Point(x,y),20,Scalar(0,255,0),2);
        if(y-25>0)
                line(frame,Point(x,y),Point(x,y-25),Scalar(0,255,0),2);
        else line(frame,Point(x,y),Point(x,0),Scalar(0,255,0),2);
        if(y+25<FRAME_HEIGHT)
                line(frame,Point(x,y),Point(x,y+25),Scalar(0,255,0),2);
        else line(frame,Point(x,y),Point(x,FRAME_HEIGHT),Scalar(0,255,0),2);
        if(x-25>0)
                line(frame,Point(x,y),Point(x-25,y),Scalar(0,255,0),2);
        else line(frame,Point(x,y),Point(0,y),Scalar(0,255,0),2);
        if(x+25<FRAME_WIDTH)
                line(frame,Point(x,y),Point(x+25,y),Scalar(0,255,0),2);
        else line(frame,Point(x,y),Point(FRAME_WIDTH,y),Scalar(0,255,0),2);

        putText(frame,intToString(x)+","+intToString(y),Point(x,y+30),1,1,Scalar(0,255,0),2);

}
void morphOps(Mat &thresh){

        //create structuring element that will be used to "dilate" and "erode" image.
        //the element chosen here is a 3px by 3px rectangle

        Mat erodeElement = getStructuringElement( MORPH_RECT,Size(3,3));
        //dilate with larger element so make sure object is nicely visible
        Mat dilateElement = getStructuringElement( MORPH_RECT,Size(8,8));

        erode(thresh,thresh,erodeElement);
        erode(thresh,thresh,erodeElement);


        dilate(thresh,thresh,dilateElement);
        dilate(thresh,thresh,dilateElement);



}
void trackFilteredObject(int &x, int &y, Mat threshold, Mat &cameraFeed){

        Mat temp;
        threshold.copyTo(temp);
        //these two vectors needed for output of findContours
        vector< vector<Point> > contours;
        vector<Vec4i> hierarchy;
        //find contours of filtered image using openCV findContours function
        findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );
        //use moments method to find our filtered object
        double refArea = 0;
        bool objectFound = false;
        if (hierarchy.size() > 0) {
                int numObjects = hierarchy.size();
                //if number of objects greater than MAX_NUM_OBJECTS we have a noisy filter
                if(numObjects<MAX_NUM_OBJECTS){
                        for (int index = 0; index >= 0; index = hierarchy[index][0]) {

                                Moments moment = moments((cv::Mat)contours[index]);
                                double area = moment.m00;

                                //if the area is less than 20 px by 20px then it is probably just noise
                                //if the area is the same as the 3/2 of the image size, probably just a bad filter
                                //we only want the object with the largest area so we safe a reference area each
                                //iteration and compare it to the area in the next iteration.
                                if(area>MIN_OBJECT_AREA && area<MAX_OBJECT_AREA && area>refArea){
                                        x = moment.m10/area;
                                        y = moment.m01/area;
                                        objectFound = true;
                                        refArea = area;
                                }else objectFound = false;


                        }
                        //let user know you found an object
                        if(objectFound ==true){
                                putText(cameraFeed,"Tracking Object",Point(0,50),2,1,Scalar(0,255,0),2);
                                //draw object location on screen
                                drawObject(x,y,cameraFeed);}

                }else putText(cameraFeed,"TOO MUCH NOISE! ADJUST FILTER",Point(0,50),1,2,Scalar(0,0,255),2);
        }
}
int main(int argc, char* argv[])
{
        //some boolean variables for different functionality within this
        //program
        bool trackObjects = true;
        bool useMorphOps = true;
        //Matrix to store each frame of the webcam feed
        Mat cameraFeed;
        //matrix storage for HSV image
        Mat HSV;
        //matrix storage for binary threshold image
        Mat threshold;
        //x and y values for the location of the object

        int x=0, y=0;
        //create slider bars for HSV filtering
        createTrackbars();
        //video capture object to acquire webcam feed
        VideoCapture capture;
        //open capture object at location zero (default location for webcam)
        capture.open(0);
        //set height and width of capture frame
        capture.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH);
        capture.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT);

        HSV.create( Size( FRAME_WIDTH, FRAME_HEIGHT), CV_8UC3);
        //start an infinite loop where webcam feed is copied to cameraFeed matrix
        //all of our operations will be performed within this loop
        while(1){
                //store image to matrix
                capture.read(cameraFeed);
                //convert frame from BGR to HSV colorspace
                cvtColor(cameraFeed,HSV,COLOR_BGR2HSV);
       
                //filter HSV image between values and store filtered image to
                //threshold matrix
                inRange(HSV,Scalar(H_MIN,S_MIN,V_MIN),Scalar(H_MAX,S_MAX,V_MAX),threshold);
                //perform morphological operations on thresholded image to eliminate noise
                //and emphasize the filtered object(s)
                if(useMorphOps)
                        morphOps(threshold);
                //pass in thresholded frame to our object tracking function
                //this function will return the x and y coordinates of the
                //filtered object
                if(trackObjects)
                {
                                trackFilteredObject(x,y,threshold,cameraFeed);
                                drawObject( x, y, threshold);
                }


                //show frames
                imshow(windowName2,threshold);
                imshow(windowName,cameraFeed);
                imshow(windowName1,HSV);
               
                //delay 30ms so that screen can refresh.
                //image will not appear without this waitKey() command
                waitKey(30);
        }

        return 0;
}
回复 支持 反对

使用道具 举报

发表于 2014-4-3 23:05:10 | 显示全部楼层
kakaweek 发表于 2014-4-3 18:31
能看看你说的代码吗?我真的也没有看到,我把hsv三空间分理出来了,可是提取蓝色时总是不知如何定义。可 ...


#include <sstream>
#include <string>
#include <iostream>
#include <opencv\highgui.h>
#include <opencv\cv.h>

using namespace cv;
//initial min and max HSV filter values.
//these will be changed using trackbars
int H_MIN = 0;
int H_MAX = 256;
int S_MIN = 0;
int S_MAX = 256;
int V_MIN = 0;
int V_MAX = 256;
//default capture width and height
const int FRAME_WIDTH = 640;
const int FRAME_HEIGHT = 480;
//max number of objects to be detected in frame
const int MAX_NUM_OBJECTS=50;
//minimum and maximum object area
const int MIN_OBJECT_AREA = 20*20;
const int MAX_OBJECT_AREA = FRAME_HEIGHT*FRAME_WIDTH/1.5;
//names that will appear at the top of each window
const string windowName = "Original Image";
const string windowName1 = "HSV Image";
const string windowName2 = "Thresholded Image";
const string windowName3 = "After Morphological Operations";
const string trackbarWindowName = "Trackbars";
void on_trackbar( int, void* )
{//This function gets called whenever a
        // trackbar position is changed





}
string intToString(int number){


        std::stringstream ss;
        ss << number;
        return ss.str();
}
void createTrackbars(){
        //create window for trackbars


        namedWindow(trackbarWindowName,0);
        //create memory to store trackbar name on window
        char TrackbarName[50];
        sprintf( TrackbarName, "H_MIN", H_MIN);
        sprintf( TrackbarName, "H_MAX", H_MAX);
        sprintf( TrackbarName, "S_MIN", S_MIN);
        sprintf( TrackbarName, "S_MAX", S_MAX);
        sprintf( TrackbarName, "V_MIN", V_MIN);
        sprintf( TrackbarName, "V_MAX", V_MAX);
        //create trackbars and insert them into window
        //3 parameters are: the address of the variable that is changing when the trackbar is moved(eg.H_LOW),
        //the max value the trackbar can move (eg. H_HIGH),
        //and the function that is called whenever the trackbar is moved(eg. on_trackbar)
        //                                  ---->    ---->     ---->      
        createTrackbar( "H_MIN", trackbarWindowName, &H_MIN, H_MAX, on_trackbar );
        createTrackbar( "H_MAX", trackbarWindowName, &H_MAX, H_MAX, on_trackbar );
        createTrackbar( "S_MIN", trackbarWindowName, &S_MIN, S_MAX, on_trackbar );
        createTrackbar( "S_MAX", trackbarWindowName, &S_MAX, S_MAX, on_trackbar );
        createTrackbar( "V_MIN", trackbarWindowName, &V_MIN, V_MAX, on_trackbar );
        createTrackbar( "V_MAX", trackbarWindowName, &V_MAX, V_MAX, on_trackbar );


}
void drawObject(int x, int y,Mat &frame){

        //use some of the openCV drawing functions to draw crosshairs
        //on your tracked image!

        //UPDATE:JUNE 18TH, 2013
        //added 'if' and 'else' statements to prevent
        //memory errors from writing off the screen (ie. (-25,-25) is not within the window!)

        circle(frame,Point(x,y),20,Scalar(0,255,0),2);
        if(y-25>0)
                line(frame,Point(x,y),Point(x,y-25),Scalar(0,255,0),2);
        else line(frame,Point(x,y),Point(x,0),Scalar(0,255,0),2);
        if(y+25<FRAME_HEIGHT)
                line(frame,Point(x,y),Point(x,y+25),Scalar(0,255,0),2);
        else line(frame,Point(x,y),Point(x,FRAME_HEIGHT),Scalar(0,255,0),2);
        if(x-25>0)
                line(frame,Point(x,y),Point(x-25,y),Scalar(0,255,0),2);
        else line(frame,Point(x,y),Point(0,y),Scalar(0,255,0),2);
        if(x+25<FRAME_WIDTH)
                line(frame,Point(x,y),Point(x+25,y),Scalar(0,255,0),2);
        else line(frame,Point(x,y),Point(FRAME_WIDTH,y),Scalar(0,255,0),2);

        putText(frame,intToString(x)+","+intToString(y),Point(x,y+30),1,1,Scalar(0,255,0),2);

}
void morphOps(Mat &thresh){

        //create structuring element that will be used to "dilate" and "erode" image.
        //the element chosen here is a 3px by 3px rectangle

        Mat erodeElement = getStructuringElement( MORPH_RECT,Size(3,3));
        //dilate with larger element so make sure object is nicely visible
        Mat dilateElement = getStructuringElement( MORPH_RECT,Size(8,8));

        erode(thresh,thresh,erodeElement);
        erode(thresh,thresh,erodeElement);


        dilate(thresh,thresh,dilateElement);
        dilate(thresh,thresh,dilateElement);



}
void trackFilteredObject(int &x, int &y, Mat threshold, Mat &cameraFeed){

        Mat temp;
        threshold.copyTo(temp);
        //these two vectors needed for output of findContours
        vector< vector<Point> > contours;
        vector<Vec4i> hierarchy;
        //find contours of filtered image using openCV findContours function
        findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );
        //use moments method to find our filtered object
        double refArea = 0;
        bool objectFound = false;
        if (hierarchy.size() > 0) {
                int numObjects = hierarchy.size();
                //if number of objects greater than MAX_NUM_OBJECTS we have a noisy filter
                if(numObjects<MAX_NUM_OBJECTS){
                        for (int index = 0; index >= 0; index = hierarchy[index][0]) {

                                Moments moment = moments((cv::Mat)contours[index]);
                                double area = moment.m00;

                                //if the area is less than 20 px by 20px then it is probably just noise
                                //if the area is the same as the 3/2 of the image size, probably just a bad filter
                                //we only want the object with the largest area so we safe a reference area each
                                //iteration and compare it to the area in the next iteration.
                                if(area>MIN_OBJECT_AREA && area<MAX_OBJECT_AREA && area>refArea){
                                        x = moment.m10/area;
                                        y = moment.m01/area;
                                        objectFound = true;
                                        refArea = area;
                                }else objectFound = false;


                        }
                        //let user know you found an object
                        if(objectFound ==true){
                                putText(cameraFeed,"Tracking Object",Point(0,50),2,1,Scalar(0,255,0),2);
                                //draw object location on screen
                                drawObject(x,y,cameraFeed);}

                }else putText(cameraFeed,"TOO MUCH NOISE! ADJUST FILTER",Point(0,50),1,2,Scalar(0,0,255),2);
        }
}
int main(int argc, char* argv[])
{
        //some boolean variables for different functionality within this
        //program
        bool trackObjects = true;
        bool useMorphOps = true;
        //Matrix to store each frame of the webcam feed
        Mat cameraFeed;
        //matrix storage for HSV image
        Mat HSV;
        //matrix storage for binary threshold image
        Mat threshold;
        //x and y values for the location of the object

        int x=0, y=0;
        //create slider bars for HSV filtering
        createTrackbars();
        //video capture object to acquire webcam feed
        VideoCapture capture;
        //open capture object at location zero (default location for webcam)
        capture.open(0);
        //set height and width of capture frame
        capture.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH);
        capture.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT);

        HSV.create( Size( FRAME_WIDTH, FRAME_HEIGHT), CV_8UC3);
        //start an infinite loop where webcam feed is copied to cameraFeed matrix
        //all of our operations will be performed within this loop
        while(1){
                //store image to matrix
                capture.read(cameraFeed);
                //convert frame from BGR to HSV colorspace
                cvtColor(cameraFeed,HSV,COLOR_BGR2HSV);
       
                //filter HSV image between values and store filtered image to
                //threshold matrix
                inRange(HSV,Scalar(H_MIN,S_MIN,V_MIN),Scalar(H_MAX,S_MAX,V_MAX),threshold);
                //perform morphological operations on thresholded image to eliminate noise
                //and emphasize the filtered object(s)
                if(useMorphOps)
                        morphOps(threshold);
                //pass in thresholded frame to our object tracking function
                //this function will return the x and y coordinates of the
                //filtered object
                if(trackObjects)
                {
                                trackFilteredObject(x,y,threshold,cameraFeed);
                                drawObject( x, y, threshold);
                }


                //show frames
                imshow(windowName2,threshold);
                imshow(windowName,cameraFeed);
                imshow(windowName1,HSV);
               
                //delay 30ms so that screen can refresh.
                //image will not appear without this waitKey() command
                waitKey(30);
        }

        return 0;
}



不好意思,我昨天发了帖子,但是也不知道是被删了还是没发上,郁闷。
回复 支持 反对

使用道具 举报

发表于 2014-4-3 23:06:45 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-4 18:42:16 | 显示全部楼层

我调试 你的程序,直接中断了。我现在的想法是如果能转换到HSV,然后遍历整张图片,将非蓝色的部分把它颜色设为白色,那么那个蓝色的部分不就显示出来了吗?请问这样的形式,应该如何编写呢?我刚学opencv,很不熟悉,请你指导一下,谢谢你
回复 支持 反对

使用道具 举报

发表于 2014-4-5 00:50:37 | 显示全部楼层
kakaweek 发表于 2014-4-4 18:42
我调试 你的程序,直接中断了。我现在的想法是如果能转换到HSV,然后遍历整张图片,将非蓝色的部分把它颜 ...

在while循环里随便设置个断点,f5到那个断点停止后,取消那个断点,再f5就可以运行了。
回复 支持 反对

使用道具 举报

发表于 2014-4-5 00:52:53 | 显示全部楼层
kakaweek 发表于 2014-4-4 18:42
我调试 你的程序,直接中断了。我现在的想法是如果能转换到HSV,然后遍历整张图片,将非蓝色的部分把它颜 ...

转换为hsv后,把亮度部分,也就是v分量提取出来,用findcontours和drawcontours函数把矩形框外面的地方给全255或者0值,都可以。findcontours的参数给这两个,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE。drawcontours用这个参数CV_FILLED。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-8 18:40:39 | 显示全部楼层
20世纪少年 发表于 2014-4-5 00:52
转换为hsv后,把亮度部分,也就是v分量提取出来,用findcontours和drawcontours函数把矩形框外面的地方给 ...

你好,我现在把蓝色部分分离出来了,可是怎么实现它的截图呢,自动把蓝色部分截取出来。绘制矩形框出了问题。你可以帮我实现以下吗?谢谢你

待截取图形

待截取图形
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-8 18:42:35 | 显示全部楼层
20世纪少年 发表于 2014-4-5 00:52
转换为hsv后,把亮度部分,也就是v分量提取出来,用findcontours和drawcontours函数把矩形框外面的地方给 ...

我感觉这个自动截取其中图像,就和人脸识别中,识别出脸之后,截取脸型是一个类型。可编程就是不能实现它,真是渴望得到你的帮助啊,这个假期都为它所困啊。谢谢你
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-8 18:42:41 | 显示全部楼层
20世纪少年 发表于 2014-4-5 00:52
转换为hsv后,把亮度部分,也就是v分量提取出来,用findcontours和drawcontours函数把矩形框外面的地方给 ...

我感觉这个自动截取其中图像,就和人脸识别中,识别出脸之后,截取脸型是一个类型。可编程就是不能实现它,真是渴望得到你的帮助啊,这个假期都为它所困啊。谢谢你
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-9 03:53:27 | 显示全部楼层
20世纪少年 发表于 2014-4-5 00:50
在while循环里随便设置个断点,f5到那个断点停止后,取消那个断点,再f5就可以运行了。 ...

遍历整个图片像素点,求出四个非255极值(X最大,X最小,Y最大,Y最小),然后你就找到了四个边界,然后用掩码图像处理就可以剪切出图像。
我现在进行的代码是:
IplImage *pImg=cvLoadImage("1.jpg",1); //加载图片
if (pImg==0)
{
                printf("Can't find the picture!\n"); //不能载入
}
else
{
                printf("Can find the image!\n");  //成功载入
               
                cvNamedWindow("Image",1);
                cvShowImage("Image",pImg);
                cvWaitKey(0);
                cvDestroyWindow( "Image" );//销毁窗口
                cvReleaseImage( &pImg ); //释放图像
}

获取图像像素:
CvScalar s;
for(i=0;i<pImg->height;i++)
                {
                        for(j=0;j<pImg->width;j++)
                        {
                                s=cvGet2D(pImg,i,j);                           
                                
                                printf("B=%f, G=%f, R=%f ",s.val[0],s.val[1],s.val[2]);
                                s.val[0]=180;
                                s.val[1]=90;
                                s.val[2]=0;      //就是图中这蓝色的RGB值
                                cvSet2D(pImg,i,j,s);                           
                        }
                }
下面我想找到蓝色部分左上角第一个点(蓝色部分最小的i和最小的j),和右下角(蓝色部分最大的像素点i和最大的j),请大家帮帮忙?往后怎么提取呢,然后用矩形ROI可以截取剪切出想要的蓝色部分。请大家贴个代码出来,谢谢了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|OpenCV中文网站

GMT+8, 2024-5-19 09:52 , Processed in 0.010572 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表