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

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 閱讀(941) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網站導航: 博客園   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>
            蜜桃精品久久久久久久免费影院| 久久欧美中文字幕| 亚洲视频一区在线| 亚洲综合色婷婷| 欧美国产日产韩国视频| 国产嫩草影院久久久久 | 91久久黄色| 亚洲图片欧洲图片日韩av| 久久男人av资源网站| 亚洲高清一区二区三区| 国产欧美日韩免费| 99精品国产一区二区青青牛奶| 久久久999国产| 亚洲一区亚洲二区| 欧美日韩精品一区二区天天拍小说 | 午夜伦理片一区| 亚洲国产精品成人va在线观看| 亚洲精品欧美日韩专区| 久久久亚洲影院你懂的| 国产日韩欧美一二三区| 亚洲综合色噜噜狠狠| 亚洲蜜桃精久久久久久久| 欧美成年人网| 亚洲精品视频免费观看| 亚洲第一精品电影| 免费观看成人鲁鲁鲁鲁鲁视频 | 亚洲九九精品| 亚洲激情视频在线播放| 欧美激情第10页| 夜夜嗨网站十八久久| 亚洲欧洲日韩综合二区| 欧美美女bbbb| 亚洲婷婷在线| 午夜精品99久久免费| 国产婷婷色一区二区三区| 欧美一区二区精品| 欧美一区二区精品在线| 精品动漫3d一区二区三区免费版| 麻豆freexxxx性91精品| 久久久精品免费视频| 亚洲激情精品| 亚洲精品日日夜夜| 国产精品区二区三区日本| 欧美自拍偷拍午夜视频| 久久精品欧美日韩| 亚洲精品一区二区三区蜜桃久| 亚洲乱亚洲高清| 国产农村妇女精品一二区| 久久一区二区三区四区| 牛人盗摄一区二区三区视频| 99精品视频网| 亚洲在线视频观看| 精品999网站| 亚洲欧美在线网| 久久精品1区| 9人人澡人人爽人人精品| 亚洲一二三区在线观看| 黄网站免费久久| 亚洲啪啪91| 国产免费成人| 亚洲大片在线| 国产精品色婷婷| 亚洲第一主播视频| 国产免费观看久久| 亚洲欧洲另类国产综合| 久久久一区二区三区| 欧美日韩在线播放| 久久精品盗摄| 欧美国产欧美亚州国产日韩mv天天看完整| 亚洲一区二区三区四区五区午夜| 久久国产日韩| 国产欧美va欧美va香蕉在| 欧美不卡在线| 国产欧美日韩高清| 亚洲精品一品区二品区三品区| 国产日韩亚洲欧美综合| 亚洲人成亚洲人成在线观看| 国产亚洲综合性久久久影院| 亚洲精品日韩激情在线电影| 在线高清一区| 欧美一级在线亚洲天堂| 亚洲一区二区三区精品视频| 狂野欧美性猛交xxxx巴西| 欧美在线视频不卡| 欧美视频在线观看| 亚洲高清视频在线| 国产一区二区精品| 日韩视频一区| 亚洲精品美女| 久久久噜噜噜久噜久久| 香蕉乱码成人久久天堂爱免费| 欧美高清视频一区| 欧美二区在线| 在线精品视频一区二区三四| 亚欧成人精品| 午夜一区在线| 国产精品超碰97尤物18| 亚洲人www| 亚洲精品偷拍| 欧美成人国产va精品日本一级| 久久综合电影| 精品999成人| 久久国产88| 久久久久国色av免费看影院| 国产乱理伦片在线观看夜一区| 亚洲伦理在线免费看| 这里只有精品电影| 欧美日韩在线精品| 一区二区三区欧美日韩| 亚洲天堂av综合网| 欧美小视频在线观看| 艳女tv在线观看国产一区| 一区二区三区蜜桃网| 亚洲专区欧美专区| 亚洲免费影视第一页| 国产精品激情偷乱一区二区∴| 99国产精品久久久| 亚洲一区二区视频在线观看| 欧美香蕉视频| 亚洲欧美一区二区三区久久 | 欧美成人精品1314www| 欧美电影免费观看高清| 亚洲精品视频中文字幕| 欧美日韩综合精品| 亚洲午夜久久久久久久久电影院| 欧美一区1区三区3区公司| 国产免费一区二区三区香蕉精| 亚洲欧美日韩精品综合在线观看| 久久精品视频网| 欧美电影免费| 亚洲永久在线| 国产精品综合视频| 久久精品伊人| 亚洲国产美女| 亚洲一区bb| 国产午夜精品久久久久久免费视| 久久精品91久久香蕉加勒比| 亚洲高清毛片| 午夜亚洲视频| 国模 一区 二区 三区| 欧美成人免费在线视频| 亚洲午夜小视频| 免费成人高清在线视频| 一区二区三区**美女毛片| 国产精品老女人精品视频| 久久精品91久久久久久再现| 亚洲韩国青草视频| 欧美一区三区三区高中清蜜桃| 亚洲国产高清一区二区三区| 欧美日韩日本国产亚洲在线| 久久激情综合网| 亚洲一级二级| 亚洲人成在线观看一区二区| 欧美综合激情网| 艳女tv在线观看国产一区| 国语自产精品视频在线看抢先版结局 | 日韩特黄影片| 激情成人综合网| 国产精品一区毛片| 欧美日韩一本到| 久久在线视频在线| 香蕉av福利精品导航| 99视频有精品| 亚洲精品国产精品国自产观看| 米奇777在线欧美播放| 欧美一级久久久久久久大片| 亚洲无线观看| 亚洲视频综合在线| 日韩视频精品在线| 亚洲欧洲日产国产综合网| 伊人色综合久久天天| 国产亚洲成av人片在线观看桃| 欧美日韩综合另类| 欧美日韩不卡视频| 欧美成人国产一区二区| 久久综合九色综合久99| 性欧美1819sex性高清| 亚洲六月丁香色婷婷综合久久| 亚洲欧美国产视频| 99在线精品观看| 国产在线精品一区二区中文| 美女999久久久精品视频| 性高湖久久久久久久久| 亚洲一本视频| 一区二区三区国产在线| 亚洲国内在线| 欧美国产一区视频在线观看| 麻豆久久婷婷| 久久久久一本一区二区青青蜜月| 欧美在线观看一二区| 亚洲视频免费在线| 亚洲精品视频免费观看| 欧美日韩精品一区二区在线播放| 欧美裸体一区二区三区| 欧美高清视频在线| 蜜臀av在线播放一区二区三区| 久久综合伊人77777麻豆| 欧美一区二区免费| 香蕉亚洲视频| 午夜国产精品视频免费体验区|