青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Shape Detection & Tracking using Contours

https://opencv-srf.blogspot.jp/2011/09/object-detection-tracking-using-contours.html
In the previous tutorial, we could detect and track an object using color separation. But we could not identify the shape of the object there. In this tutorial, let's see how to identify a shape and position of an object using contours with OpenCV.

Using contours with OpenCV, you can get a sequence of points of vertices of each white patch (White patches are considered as polygons). As example, you will get 3 points (vertices)  for a triangle, and 4 points for quadrilaterals. So, you can identify any polygon by the number of vertices of that polygon. You can even identify features of polygons such as convexity, concavity, equilateral and etc by calculating and comparing distances between vertices. 

Let's see how this can be done with OpenCV. All you need, is a binary image in which your objects should be white and the background should be black.

Binary Image


Now I am going to identify triangles and  quadrilaterals and heptagon in the above image using a C++ application with OpenCV.  I'll draw a line along the perimeter of every identified polygon with colors blue for triangle, green for quadrilaterals and red for heptagons. Here is the code.


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
using namespace std;

int main()
{

IplImage* img =  cvLoadImage("C:/Users/SHERMAL/Desktop/FindingContours.png");

//show the original image
cvNamedWindow("Raw");
cvShowImage("Raw",img);

//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1); 
cvCvtColor(img,imgGrayScale,CV_BGR2GRAY);

//thresholding the grayscale image to get better results
cvThreshold(imgGrayScale,imgGrayScale,128,255,CV_THRESH_BINARY);  

CvSeq* contours;  //hold the pointer to a contour in the memory block
CvSeq* result;   //hold sequence of points of a contour
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours

//finding all contours in the image
cvFindContours(imgGrayScale, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

//iterating through each contour
while(contours)
{
//obtain a sequence of points of contour, pointed by the variable 'contour'
result = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0);
       
//if there are 3  vertices  in the contour(It should be a triangle)
if(result->total==3 )
{
//iterating through each point
CvPoint *pt[3];
for(int i=0;i<3;i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}

//drawing lines around the triangle
cvLine(img, *pt[0], *pt[1], cvScalar(255,0,0),4);
cvLine(img, *pt[1], *pt[2], cvScalar(255,0,0),4);
cvLine(img, *pt[2], *pt[0], cvScalar(255,0,0),4);

}

//if there are 4 vertices in the contour(It should be a quadrilateral)
else if(result->total==4 )
{
//iterating through each point
CvPoint *pt[4];
for(int i=0;i<4;i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}

//drawing lines around the quadrilateral
cvLine(img, *pt[0], *pt[1], cvScalar(0,255,0),4);
cvLine(img, *pt[1], *pt[2], cvScalar(0,255,0),4);
cvLine(img, *pt[2], *pt[3], cvScalar(0,255,0),4);
cvLine(img, *pt[3], *pt[0], cvScalar(0,255,0),4);
}

//if there are 7  vertices  in the contour(It should be a heptagon)
else if(result->total ==7  )
{
//iterating through each point
CvPoint *pt[7];
for(int i=0;i<7;i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}

//drawing lines around the heptagon
cvLine(img, *pt[0], *pt[1], cvScalar(0,0,255),4);
cvLine(img, *pt[1], *pt[2], cvScalar(0,0,255),4);
cvLine(img, *pt[2], *pt[3], cvScalar(0,0,255),4);
cvLine(img, *pt[3], *pt[4], cvScalar(0,0,255),4);
cvLine(img, *pt[4], *pt[5], cvScalar(0,0,255),4);
cvLine(img, *pt[5], *pt[6], cvScalar(0,0,255),4);
cvLine(img, *pt[6], *pt[0], cvScalar(0,0,255),4);
}

//obtain the next contour
contours = contours->h_next;
}

//show the image in which identified shapes are marked   
cvNamedWindow("Tracked");
cvShowImage("Tracked",img);
   
cvWaitKey(0); //wait for a key press

//cleaning up
cvDestroyAllWindows(); 
cvReleaseMemStorage(&storage);
cvReleaseImage(&img);
cvReleaseImage(&imgGrayScale);

return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
You can download this OpenCV visual c++ project from here(The downloaded file is a compressed .rar folder. So, you have to extract it using Winrar or other suitable software) 


White blobs with different shapes are detected using contours with OpenCV functions

As you can see, triangles are marked with blue, quadrilaterals are marked with green and heptagons are marked with red. So, now it is obvious that this method is capable of identifying shapes. 

Explanation

Here I have converted the original image in to gray scale. It is because this method works only with gray scale image with single channel. To get better results, I threshold the gray-scale image using 'cvThreshold' function. You can use your own way to threshold the image. Then I find all contours in the thresholded image and identify and track all triangles, quadrilaterals and heptagons.

Let's discuss new OpenCV functions, found in this application.



  • cvThreshold( const Mat& srcMat& dst, double threshVal, double max, int thresholdType )

applies a fix level threshold to the each element of 'src' array write a value to corresponding array element of 'dst'

Arguements -
  • const Mat& src - Source array (This should be single channel)
  • Mat& dst - Destination array which has the same size and same type as the 'src'
  • double threshVal - Threshold value
  • double max - Maximum value to use with 'THRESH_BINARY' and 'THRESH_BINARY_INV' which are thresholding types
  • int thresholdType - You can use one of the following for this arguement
    • THRESH_BINARY
                       dst(x,y)=max,             if src(x,y) > ThreshVal
                       dst(x,y)=0,                 if src(x,y) < ThreshVal
  • THRESH_BINARY_INV
                      dst(x,y)=0,                  if src(x,y) > ThreshVal
                      dst(x,y)=max,              if src(x,y) < ThreshVal
  • THRESH_TOZERO
                      dst(x,y)=src(x,y),       if src(x,y) > ThreshVal
                            dst(x,y)=0,                 if src(x,y) < ThreshVal
  • THRESH_TOZERO_INV
                      dst(x,y)=0,                  if src(x,y) > ThreshVal
                      dst(x,y)=src(x,y),        if src(x,y) < ThreshVal
    • THRESH_TRUNC
                      dst(x,y)=threshVal,    if src(x,y) > ThreshVal
                      dst(x,y)=src(x,y),        if src(x,y) < ThreshVal


In the above application, I have used 'THRESH_BINARY', because I want to assign 255 (white) where the objects are located and 0 (black) elsewhere.


  • cvCreateMemStorage(int byteSize)
Creates memory storage which has the capacity specified by the parameter 'byteSize'. But if byteSize=0, the allocated capacity is the default value(usually 64 Kb)


  • cvFindContours( CvArr* img, CvMemStorage* str, CvSeq** first_contour, int header_size, int mode, int method, CvPoint offset )
Find all contours in a binary image
Arguments - 
  • CvArr* img - Source image (This should be 8 bit single channel). All non-zero pixels are considered as 1 and all zero remain zero.
  • CvMemStorage* str - Memory blocks to store all obtained contours
  • CvSeq** first_contour - store a pointer to the first contour in the memory block, 'str'
  • int header_size - size of the sequence header
  • int mode - mode of retrieval of contours from the image
                You have to choose one of the following
    • CV_RETR_LIST - Retrieves all of the contours and put them in a list
    • CV_RETR_EXTERNAL - Retrieves only the extreme outer contours
    • CV_RETR_CCOMP - Retrieves all of the contours and organizes them into a two-level hierarchy: on the top level are the external boundaries of the components, on the second level are the boundaries of the holes
    • CV_RETR_TREE - Retrieves all of the contours and reconstructs the full hierarchy of nested contours

  • int method - Approximation method
                  You have to choose one of the following

    • CV_CHAIN_CODE - Outputs contours in the Freeman chain code
    • CV_CHAIN_APPROX_NONE - Translates all of the points from the chain code into points
    • CV_CHAIN_APPROX_SIMPLE - Compresses horizontal, vertical, and diagonal segments and leaves only their end points
    • CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS - Applies one of the flavors of the Teh-Chin chain approximation algorithm.
    • CV_LINK_RUNS - uses a completely different contour retrieval algorithm by linking horizontal segments of 1’s. Only the 'CV_RETR_LIST' retrieval mode can be used with this method.
  • CvPoint offset - Offset by which every contour point should be shifted. This is useful when we have set ROI (Region Of Interest) in the image. Normally we set the offset to 'cvPoint(0,0)'

  • cvApproxPoly( const void* src, int header_size, CvMemStorage* storage, int method, double para1, int para2 )
Approximate polygonal curves with specified precision

arguments - 
  • const void* src - Sequence of points
  • int header_size -  size of the sequence header
  • CvMemStorage* storage - memory block that contains all contours
  • int method - Approximation method. (The only method, available to use for this argument is 'CV_POLY_APPROX_DP')
  • double para1 - approximation accuracy
  • int para2 - Determines whether the single sequence should be approximated or all sequences in the same level or below 

  • cvGetSeqElem( const CvSeq* seq, int index )
Returns a pointer to the element of 'seq' at 'index'

  • cvReleaseMemStorage( CvMemStorage** storage )
Deallocate memory blocks which have been allocated by 'cvCreateMemStorage()' function




Real World Example


The above example is not really useful in practical situation. Usually, there are lots of noises in an image such as irregular lighting, shadows, camera irregularities and etc. So, above application as it is, cannot be used to identify shapes in a real image. It should be modified to cope with these noises. And images usually have 3 channels (BGR color). So, it should be converted into grey-scale which has only one channel. 

Here is a real world image of an arena of a robot soccer, taken from a camera.

Robot Arena

Here, we are going to detect and mark the perimeter of each triangle in the image with a blue line. Let's see the modified OpenCV c++ application which accomplish the above task.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
using namespace std;

int main()
{

IplImage* img =  cvLoadImage("C:/Users/SHERMAL/Desktop/DetectingContours.jpg");

//show the original image
cvNamedWindow("Original");
cvShowImage("Original",img);

 //smooth the original image using Gaussian kernel to remove noise
cvSmooth(imgimg, CV_GAUSSIAN,3,3);

//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1); 
cvCvtColor(img,imgGrayScale,CV_BGR2GRAY);

cvNamedWindow("GrayScale Image");
cvShowImage("GrayScale Image",imgGrayScale);

//thresholding the grayscale image to get better results
cvThreshold(imgGrayScale,imgGrayScale,100,255,CV_THRESH_BINARY_INV);

cvNamedWindow("Thresholded Image");
cvShowImage("Thresholded Image",imgGrayScale);

CvSeq* contour;  //hold the pointer to a contour
CvSeq* result;   //hold sequence of points of a contour
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours

//finding all contours in the image
cvFindContours(imgGrayScale, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

//iterating through each contour
while(contour)
{
//obtain a sequence of points of the countour, pointed by the variable 'countour'
result = cvApproxPoly(contour, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0);
       
//if there are 3 vertices  in the contour and the area of the triangle is more than 100 pixels
if(result->total==3 && fabs(cvContourArea(result, CV_WHOLE_SEQ))>100 )
{
//iterating through each point
CvPoint *pt[3];
for(int i=0;i<3;i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}

//drawing lines around the triangle
cvLine(img, *pt[0], *pt[1], cvScalar(255,0,0),4);
cvLine(img, *pt[1], *pt[2], cvScalar(255,0,0),4);
cvLine(img, *pt[2], *pt[0], cvScalar(255,0,0),4);

}

//obtain the next contour
contour = contour->h_next;
}

//show the image in which identified shapes are marked   
cvNamedWindow("Tracked");
cvShowImage("Tracked",img);
   
cvWaitKey(0); //wait for a key press

//cleaning up
cvDestroyAllWindows(); 
cvReleaseMemStorage(&storage);
cvReleaseImage(&img);
cvReleaseImage(&imgGrayScale);

return 0;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
You can download this OpenCV visual c++ project from here(The downloaded file is a compressed .rar folder. So, you have to extract it using Winrar or other suitable software)


converted to gray scale Image with OpenCV cvCvtColor function
Gray scale Image

Thresholded the image using OpenCV cvThreshold function
Thresholded Image

Triangles Detected with OpenCV using contours with 3 vertices
Triangles Detected


In the same way, any shapes with any sizes can be detected with OpenCV.


Explanation

To reduce the noise level of the original image, I have smoothed the original image with a Gaussian kernel. 
Further you can change the 5th argument of cvApproxPoly() function to cope with the noise. In the above example, I have used cvContourPerimeter(contour)*0.02 as the 5th argument of cvApproxPoly(). You can try cvContourPerimeter(contour)*0.01 or cvContourPerimeter(contour)*0.04 or any other value and see the difference of the output yourselves.
Still there may be very small triangles, formed due to the noise. Therefore all triangles with areas less than 100 pixels are filtered out. 

Here are the new OpenCV functions, found in the above example.
  • cvContourArea(const CvArr* contour, CvSlice slice)
Calculate the area enclosed by sequence of contour points. 
  • const CvArr* contour - array of vertices of the contour
  • CvSlice slice - starting and ending point of the contour. 'CV_WHOLE_SEQ' will take the whole contour to calculate the area
The orientation of contour affects the area sign. So, this function may return a negative value. So, it should be used fabs() function to get the absolute value.

  • fabs(double x)

This function returns the absolute value of any floating point number. ( This is a C function, not a OpenCV function)


Tracking two Triangles in a Video


Here I am going to track the two triangles in a video. The blue triangle is marked with red and the green triangle is marked with blue. 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
using namespace std;

IplImage* imgTracking=0;

int lastX1 = -1;
int lastY1 = -1;

int lastX2 = -1;
int lastY2 = -1;

void trackObject(IplImage* imgThresh){
CvSeq* contour;  //hold the pointer to a contour
CvSeq* result;     //hold sequence of points of a contour
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours

//finding all contours in the image
cvFindContours(imgThresh, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

//iterating through each contour
while(contour)
{
//obtain a sequence of points of the countour, pointed by the variable 'countour'
result = cvApproxPoly(contour, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0);
       
//if there are 3 vertices  in the contour and the area of the triangle is more than 100 pixels
if(result->total==3 && fabs(cvContourArea(result, CV_WHOLE_SEQ))>100 )
{
//iterating through each point
CvPoint *pt[3];
for(int i=0;i<3;i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}

int posX=( pt[0]->x + pt[1]->x + pt[2]->x )/3;
int posY=( pt[0]->y + pt[1]->y + pt[2]->y )/3;

if(posX > 360 ){
if(lastX1>=0 && lastY1>=0 && posX>=0 && posY>=0){
// Draw a red line from the previous point to the current point
cvLine(imgTracking, cvPoint(posX, posY), cvPoint(lastX1, lastY1), cvScalar(0,0,255), 4);
}

lastX1 = posX;
lastY1 = posY;
}
else{
if(lastX2>=0 && lastY2>=0 && posX>=0 && posY>=0){
// Draw a blue line from the previous point to the current point
cvLine(imgTracking, cvPoint(posX, posY), cvPoint(lastX2, lastY2), cvScalar(255,0,0), 4);
}

lastX2 = posX;
lastY2 = posY;
}
}

//obtain the next contour
contour = contour->h_next;
}

cvReleaseMemStorage(&storage);
}


int main(){
    //load the video file to the memory
CvCapture *capture =     cvCaptureFromAVI("E:/Projects/Robot/IESL Robot/robot/a.avi");

    if(!capture){
        printf("Capture failure\n");
        return -1;
    }
      
    IplImage* frame=0;
    frame = cvQueryFrame(capture);           
    if(!frame) return -1;
   
    //create a blank image and assigned to 'imgTracking' which has the same size of original video
    imgTracking=cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U, 3);
    cvZero(imgTracking); //covert the image, 'imgTracking' to black

    cvNamedWindow("Video");     

//iterate through each frames of the video     
    while(true){

        frame = cvQueryFrame(capture);           
        if(!frame) break;
        frame=cvCloneImage(frame); 
         
//smooth the original image using Gaussian kernel
        cvSmooth(frame, frame, CV_GAUSSIAN,3,3); 

//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(frame), 8, 1); 
cvCvtColor(frame,imgGrayScale,CV_BGR2GRAY);
          
       //thresholding the grayscale image to get better results
cvThreshold(imgGrayScale,imgGrayScale,100,255,CV_THRESH_BINARY_INV);
            
        //track the possition of the ball
        trackObject(imgGrayScale);

        // Add the tracking image and the frame
        cvAdd(frame, imgTracking, frame);
             
        cvShowImage("Video", frame);
   
        //Clean up used images
        cvReleaseImage(&imgGrayScale);            
        cvReleaseImage(&frame);

        //Wait 10mS
        int c = cvWaitKey(10);
        //If 'ESC' is pressed, break the loop
        if((char)c==27 ) break;      
    }

    cvDestroyAllWindows();
    cvReleaseImage(&imgTracking);
    cvReleaseCapture(&capture);     

    return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
You can download this OpenCV visual c++ project from here(The downloaded file is a compressed .rar folder. So, you have to extract it using Winrar or other suitable software)


Explanation

You already know how to obtain 3 vertices of a triangle with OpenCV. Averaging those 3 vertices gives you the center point of the triangle. So, it is easy to track triangles in a video.
Then, how do you identify two similar triangles separately? Here I have used a simple trick. I know that the green triangle always is in the left side of the video and the blue triangle is in the right side of the video. So, if the x coordinate of a triangle is more than (frame width)/2 = 360, then it is the blue triangle, otherwise it is the green triangle. 

Next Tutorial : 

posted on 2017-09-14 16:44 zmj 閱讀(950) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美在线啊v| 欧美中文在线字幕| 欧美视频专区一二在线观看| 一个人看的www久久| 欧美与黑人午夜性猛交久久久| 国产精品成av人在线视午夜片| 亚洲欧美中文另类| 老司机aⅴ在线精品导航| 亚洲人成网站色ww在线| 欧美日韩精品在线| 亚洲欧美中文另类| 欧美暴力喷水在线| 亚洲一区二区黄| 国产精品日韩一区二区三区| 久久久久久久999精品视频| 亚洲精品美女| 欧美在线资源| 99精品99久久久久久宅男| 国产精品影片在线观看| 欧美1区2区视频| 亚洲视频免费在线| 欧美1区2区3区| 小黄鸭精品aⅴ导航网站入口| 在线免费观看一区二区三区| 欧美三级免费| 久久全球大尺度高清视频| 99综合精品| 蜜臀a∨国产成人精品| 一区二区三区日韩| 激情欧美日韩| 国产精品视频xxxx| 欧美激情影院| 久久久www免费人成黑人精品 | 亚洲国产一区二区a毛片| 亚洲欧美成人网| 亚洲激情成人在线| 国产人妖伪娘一区91| 欧美国产欧美亚州国产日韩mv天天看完整| 亚洲伊人伊色伊影伊综合网| 亚洲国产一区二区视频| 久久久久久久久久码影片| 亚洲在线一区二区三区| 亚洲精品一区二区三区四区高清 | 亚洲专区在线| 亚洲国产一区二区三区高清| 久久久人成影片一区二区三区| 亚洲图片激情小说| 亚洲欧洲精品一区二区| 一区二区三区在线视频免费观看| 国产精品久久久久久久浪潮网站| 欧美高清在线精品一区| 久久久福利视频| 欧美在线免费| 欧美在线资源| 性娇小13――14欧美| 亚洲资源av| 亚洲午夜女主播在线直播| 亚洲精品一区二区三区蜜桃久 | 亚洲综合国产| 一区二区三区视频在线观看| 亚洲乱码国产乱码精品精可以看| 在线观看成人av| 精品不卡一区二区三区| 国产一区二区三区在线播放免费观看| 国产精品美女久久福利网站| 欧美系列电影免费观看| 欧美三区美女| 欧美日韩一区在线观看| 欧美午夜剧场| 国产精品久久77777| 国产精品久久久久久久免费软件| 欧美日韩国产黄| 欧美色图一区二区三区| 国产精品电影在线观看| 国产精品久久久久久久久久免费看| 欧美三区在线视频| 国产精品久久久久aaaa樱花| 国产精品视频自拍| 国产目拍亚洲精品99久久精品| 国产精品自拍网站| 韩曰欧美视频免费观看| 影音先锋久久久| 亚洲精品国产系列| 一区二区三区视频免费在线观看| 亚洲午夜在线观看视频在线| 亚洲欧美日韩精品在线| 久久九九99| 欧美成人激情视频| 亚洲精品一区二区三区不| 亚洲色诱最新| 久久福利资源站| 欧美国产日产韩国视频| 国产精品久久久久毛片软件| 国产欧美 在线欧美| 亚洲电影视频在线| 一区二区福利| 久久激情五月丁香伊人| 欧美风情在线| 国产精品99久久久久久宅男| 欧美一级理论性理论a| 久久综合激情| 欧美三区在线| 激情五月综合色婷婷一区二区| 亚洲精品一区二区三区四区高清 | 欧美日韩另类一区| 国产啪精品视频| 亚洲国产日韩一区二区| 亚洲午夜电影| 麻豆av一区二区三区久久| 亚洲人人精品| 午夜亚洲精品| 欧美激情综合| 国内成人自拍视频| 在线性视频日韩欧美| 久久午夜激情| 99精品欧美一区二区蜜桃免费| 欧美诱惑福利视频| 欧美日韩在线播| 亚洲高清视频一区二区| 亚洲免费网址| 亚洲福利视频免费观看| 先锋亚洲精品| 欧美色中文字幕| 亚洲国产精品悠悠久久琪琪| 欧美一区二区三区免费视| 亚洲国产精品久久久久婷婷老年| 亚洲欧美制服另类日韩| 欧美日本一道本在线视频| 激情欧美一区二区三区| 欧美亚洲一区三区| 亚洲美女在线视频| 免费看的黄色欧美网站| 国产在线观看91精品一区| 亚洲午夜女主播在线直播| 亚洲第一毛片| 久久久久国产免费免费| 国产欧美日韩激情| 亚洲综合电影| aa亚洲婷婷| 欧美日韩精品二区| 亚洲精品欧美| 欧美大片在线看免费观看| 久久av一区二区三区| 国产精品一区久久| 亚洲欧美日韩精品久久久久| 亚洲精品乱码久久久久久| 欧美不卡在线| 亚洲欧洲午夜| 欧美激情导航| 欧美成人情趣视频| 亚洲韩国日本中文字幕| 欧美成人精品在线| 久久久久久一区二区| 激情综合网址| 久久免费高清视频| 欧美制服第一页| 一区二区在线视频| 久久久亚洲高清| 久久久噜久噜久久综合| 一区二区三区在线不卡| 欧美不卡视频一区| 久久综合色影院| 亚洲精品免费在线播放| 最近中文字幕日韩精品| 欧美日韩精品免费观看视一区二区 | 欧美成人综合网站| 久久久亚洲成人| 亚洲高清一区二| 亚洲国产另类精品专区 | 亚洲国产欧美在线人成| 欧美高清视频一区二区三区在线观看| 久久夜色撩人精品| 亚洲美女免费精品视频在线观看| 亚洲激情欧美激情| 欧美视频日韩视频在线观看| 午夜在线精品偷拍| 欧美在线观看www| 91久久精品美女高潮| 亚洲精品乱码久久久久久日本蜜臀| 欧美日韩精品免费观看视频完整| 亚洲综合国产| 久久国产精品一区二区| 亚洲激情偷拍| 中文久久精品| 韩国一区二区三区美女美女秀| 免费日韩一区二区| 欧美连裤袜在线视频| 午夜精品久久久久久久| 欧美在线视频一区| 亚洲人精品午夜| 一本色道久久综合精品竹菊 | 亚洲综合精品一区二区| 欧美一区二区视频观看视频| 亚洲电影专区| 一区二区三区视频在线| 精品96久久久久久中文字幕无| 亚洲精品乱码久久久久| 国产一区三区三区| 亚洲精品色图| 一区二区三区在线高清|