日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用OPENCV视觉解数独

發布時間:2023/12/10 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用OPENCV视觉解数独 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

用OPENCV視覺解數獨

?

2010-06-29

?

看到增強視覺網站上介紹老外用視覺解SUDOKU(http://www.cvchina.info/2011/05/29/video-sudoku-solver/),覺得應該不難,于是用OPENCV和訓練好的數字分類器,也試著做一個,純屬娛樂


基本思路如下:

一,定位網格,
?1,尋找圖像中的矩形,使用OPENCV中經典找矩形(因為速度問題使用C版本)代碼就可以,將條件降低(CANNY的對比度和角度是否直角)以便找到更多的矩形。
?2,由于不一定能找到所有的矩形,需要根據找到的矩形對網格進行推算,推算出的矩形被稱為“虛擬矩形”
?3,最后對網格中的虛擬矩形根據上下的矩形進行位置修正


二,數字分析
?網格中存在兩種可能,有數據和沒有數據。我們通過對比度和輪廓大小過濾掉沒有數據的網格。
?對剩下的網格進行數字分析,使用SVM手寫數字分類器,得到該網格的數據

?

三,求解
?剩下的問題就簡單了,對得到的SUDOKU題目進行求解就可以啦

?

?

?

效果嗎,對網格和數字比較清晰的圖像效果不錯,從模糊的圖片就差一些了,主要是數字和邊框不清晰,導致矩形尋找和數字判斷錯誤,可以根據圖像的特征進行優化,但如果能做到各種圖片通吃就困難多了。

手寫數字的圖片(藍色為找到的網格,綠色為推算出的虛擬網格):



?

識別結果:

?

印刷數字的圖片(藍色為找到的網格,綠色為推算出的虛擬網格):

?

失敗的例子,由于網格不清晰,導致無法找到足夠的矩形網格:

?

?

主要代碼如下(不包括SUDOKU求解部分),

?

// Sudoku detect #include "stdafx.h" #ifdef _CH_ #pragma package <opencv> #endif #ifndef _EiC #include "opencv2/opencv.hpp" #include <stdio.h> #include <math.h> #include <string.h> #endif #include <vector> #include <list> using namespace cv; #define SHOW_IMG 0 const double MIN_CONTOUR_PROPORTION = 0.02; const int CANNY_LOW_THRESH = 0; const int CANNY_HIGH_THRESH = 30; //int thresh = 50; const double MIN_ANGLE = 0.1; //double MIN_ANGLE = 0.05; IplImage* img = 0; IplImage* img0 = 0; CvMemStorage* storage = 0; CvPoint pt[4]; const char* wndname = "Square Detection Demo"; class FilterRect { public: Rect rc; bool useFlag; FilterRect() { rc = Rect(0, 0, 0, 0); useFlag = false; } }; vector<Rect> allRects; vector<FilterRect> filterRects; const int SUDOKU_GRID_NUM = 9; const unsigned int DIFF_THRESHOLD = 16; class RtTrainData { public: float data[64]; int result; }; class ValidRect { public: Rect rc; int row; int col; bool blankFlag; bool virtualFlag; Rect contourRc; double contrast; double areaProportion; ValidRect() { rc = Rect(0, 0, 0, 0); contourRc = Rect(0, 0, 0, 0); row = 0; col = 0; blankFlag = true; virtualFlag = true; contrast = 0.0; areaProportion = 0.0; } }; ValidRect validRects[81]; typedef struct rectWithArea { CvPoint pt[4]; double area; }RectWithArea; bool compareRects(const Rect& rc1, const Rect& rc2, bool& replaceFirst) { int dx = rc1.x - rc2.x; int dy = rc1.y - rc2.y; int dw = rc1.width - rc2.width; int dh = rc1.height - rc2.height; //if((dx*dx + dy*dy + dw*dw + dh*dh) < DIFF_THRESHOLD) if((dx*dx + dy*dy + dw*dw + dh*dh) < DIFF_THRESHOLD) { if(rc1.area() > rc2.area()) replaceFirst = true; else replaceFirst = false; return true; } else return false; } double getBkInfo(Mat& src, float& highProportion, Scalar& contrast) { Mat temp, high, low; Rect rc(src.cols / 10, src.rows / 10, src.cols * 0.9, src.rows * 0.9); temp = src(rc); double thresh = threshold(temp, high, 0, 0, CV_THRESH_OTSU); //求出分割閾值 threshold(temp, high, thresh, 0, CV_THRESH_TOZERO); //分割高亮部分 threshold(temp, low, thresh, 0, CV_THRESH_TOZERO_INV); //分割低暗部分 int highCount = cv::countNonZero(high); highProportion = (float)highCount / src.total(); //highProportion = (float)highCount / (src.rows * src.cols); Scalar lowValue = mean(low); Scalar highValue = mean(high); contrast = (highValue - lowValue) / lowValue; double ret = abs(contrast.val[0]); return ret; } // helper function: // finds a cosine of angle between vectors // from pt0->pt1 and from pt0->pt2 double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 ) { double dx1 = pt1->x - pt0->x; double dy1 = pt1->y - pt0->y; double dx2 = pt2->x - pt0->x; double dy2 = pt2->y - pt0->y; return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); } // returns sequence of squares detected on the image. // the sequence is stored in the specified memory storage CvSeq* findSquares4( IplImage* img, CvMemStorage* storage ) { const int MAX_CONTOUR_SIZE = img->width * img->height / 80; const int MIN_CONTOUR_SIZE = MAX_CONTOUR_SIZE / 16; int contours_num = 0; CvSeq* contours; int i, c, l, N = 1; //11; CvSize sz = cvSize( img->width & -2, img->height & -2 ); IplImage* timg = cvCloneImage( img ); // make a copy of input image //IplImage* timg2 = cvCloneImage( img ); // make a copy of input image IplImage* gray = cvCreateImage( sz, 8, 1 ); IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 ); IplImage* tgray; CvSeq* result; double s, t; // create empty sequence that will contain points - // 4 points per square (the square's vertices) CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(RectWithArea), storage ); // select the maximum ROI in the image // with the width and height divisible by 2 cvSetImageROI( timg, cvRect( 0, 0, sz.width, sz.height )); //Only care RED //cvSetImageCOI( timg2, 3 ); //cvCopy(timg2, gray, NULL); // down-scale and upscale the image to filter out the noise cvPyrDown( timg, pyr, 7 ); cvPyrUp( pyr, timg, 7 ); tgray = cvCreateImage( sz, 8, 1 ); // find squares in every color plane of the image for( c = 0; c < 3; c++ ) { // extract the c-th color plane cvSetImageCOI( timg, c+1 ); cvCopy( timg, tgray, 0 ); // try several threshold levels for( l = 0; l < N; l++ ) { // hack: use Canny instead of zero threshold level. // Canny helps to catch squares with gradient shading if( l == 0 ) { // apply Canny. Take the upper threshold from slider // and set the lower to 0 (which forces edges merging) cvCanny( tgray, gray, CANNY_LOW_THRESH, CANNY_HIGH_THRESH, 5 ); // dilate canny output to remove potential // holes between edge segments cvDilate( gray, gray, 0, 1 ); } else { // apply threshold if l!=0: // tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0 cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY ); } //imshow("gray", gray); //waitKey(0); // find contours and store them all as a list cvFindContours( gray, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) ); // test each contour while( contours ) { contours_num++; // approximate contour with accuracy proportional // to the contour perimeter result = cvApproxPoly( contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 ); // square contours should have 4 vertices after approximation // relatively large area (to filter out noisy contours) // and be convex. // Note: absolute value of an area is used because // area may be positive or negative - in accordance with the // contour orientation if( result->total == 4 && fabs(cvContourArea(result,CV_WHOLE_SEQ)) > MIN_CONTOUR_SIZE && fabs(cvContourArea(result,CV_WHOLE_SEQ)) < MAX_CONTOUR_SIZE && cvCheckContourConvexity(result) ) { s = 0; for( i = 0; i < 5; i++ ) { // find minimum angle between joint 檢查3個角就足夠了(對四邊形來說如果三個角為直角,則第四個也為直角) // edges (maximum of cosine) if( i >= 2 ) { t = fabs(angle( (CvPoint*)cvGetSeqElem( result, i ), (CvPoint*)cvGetSeqElem( result, i-2 ), (CvPoint*)cvGetSeqElem( result, i-1 ))); s = s > t ? s : t; } } // if cosines of all angles are small // (all angles are ~90 degree) then write quandrange // vertices to resultant sequence if( s < MIN_ANGLE ) { RectWithArea rwa; for(int i=0; i<4; i++) rwa.pt[i] = *(CvPoint*)cvGetSeqElem( result, i ); rwa.area = fabs(cvContourArea(result,CV_WHOLE_SEQ)); cvSeqPush( squares, &rwa); //Add to all rects Rect rect(rwa.pt[0], rwa.pt[2]); allRects.push_back(rect); } } // take the next contour contours = contours->h_next; } } } // release all the temporary images cvReleaseImage( &gray ); cvReleaseImage( &pyr ); cvReleaseImage( &tgray ); cvReleaseImage( &timg ); return squares; } // the function draws all the squares in the image /* Sort 2d points in top-to-bottom left-to-right order */ static int cmp_func( const void* _a, const void* _b, void* userdata ) { RectWithArea* a = (RectWithArea*)_a; RectWithArea* b = (RectWithArea*)_b; return a->area < b->area ? -1 : a->area > b->area ? 1 : 0; } void drawSquares( IplImage* img, CvSeq* squares ) { cvSeqSort( squares, cmp_func, 0); CvSeqReader reader; IplImage* cpy = cvCloneImage( img ); int i; // initialize reader of the sequence cvStartReadSeq( squares, &reader, 0 ); // read 4 sequence elements at a time (all vertices of a square) for( i = 0; i < squares->total; i ++ ) { RectWithArea rwa; int count = 4; // draw the square as a closed polyline memcpy(&rwa, reader.ptr, squares->elem_size); CvPoint* rect = pt; pt[0] = rwa.pt[0]; pt[1] = rwa.pt[1]; pt[2] = rwa.pt[2]; pt[3] = rwa.pt[3]; cvPolyLine( cpy, &rect, &count, 1, 1, CV_RGB(0,255,0), 3, CV_AA, 0 ); CV_NEXT_SEQ_ELEM( squares->elem_size, reader ); //if(i>10) // break; } // show the resultant image cvShowImage( wndname, cpy ); cvReleaseImage( &cpy ); } void filterDupRect() { for(unsigned int i=0; i<allRects.size(); i++) { bool insertFlag = true; for(unsigned int j=0; j<filterRects.size(); j++) { bool replaceFlag = false; if(compareRects(filterRects[j].rc, allRects[i], replaceFlag)) { if(replaceFlag) filterRects[j].rc = allRects[i]; //Using smaller one insertFlag = false; //Have similiar, not save break; } } if(insertFlag) { FilterRect fr; fr.rc = allRects[i]; filterRects.push_back(fr); } } } int findTopLeftRect(Mat& src) { int min_dist = src.size().width + src.size().height; int index = -1; for(unsigned int j = 0; j < filterRects.size(); j ++ ) { int dist = filterRects[j].rc.x + filterRects[j].rc.y; if(dist < min_dist) { min_dist = dist; index = j; } } return index; } void updateValidRect(int col, int row, Rect rc, bool virtualFlag) { int index = col + row * 9; validRects[index].col = col; validRects[index].row = row; validRects[index].rc = rc; //validRects[index].processFlag = true; validRects[index].virtualFlag = virtualFlag; } int findNearest(Rect& rc, int offsetX, int offsetY) { int min_dist = 1000; int index = -1; for(unsigned int j = 0; j < filterRects.size(); j ++ ) { if(filterRects[j].useFlag == true) continue; int dx = abs(filterRects[j].rc.x -offsetX); int dy = abs(filterRects[j].rc.y -offsetY); int dw = abs(filterRects[j].rc.width - rc.width); int dh = abs(filterRects[j].rc.height - rc.height); int dist = dx+dy+dw+dh; if( dist < min_dist) { index = j; min_dist = dist; } } int maxDiff = rc.width / 4 + rc.height / 4; if(min_dist < maxDiff) return index; else return -1; } bool findValidRects(Mat& src) { int maxW = src.size().width; int maxH = src.size().height; int dx = 10, dy = 10; for(int row = 0; row < 9; row++) { for(int col = 0; col < 9; col++) { if((row == 0) && (col == 0)) { int index = findTopLeftRect(src); if(index>0) { updateValidRect(col, row, filterRects[index].rc, false); filterRects[index].useFlag = true; } else return false; } else if(row == 0) { Rect leftRc = validRects[col -1].rc; //Align to left int offsetX = leftRc.x + leftRc.width + dx; int offsetY = leftRc.y; int index = findNearest(leftRc, offsetX, offsetY); if(index>0) //Find rect { updateValidRect(col, row, filterRects[index].rc, false); filterRects[index].useFlag = true; } else if( (offsetX + leftRc.width) > maxW) //over the scale { return false; } else { leftRc.x = offsetX; leftRc.y = offsetY; updateValidRect(col, row, leftRc, true); } } else if(col == 0) { Rect upRc = validRects[9*(row-1) + col ].rc; //Align to top int offsetX = upRc.x; int offsetY = upRc.y + upRc.height + dy; int index = findNearest(upRc, offsetX, offsetY); if(index>0) { updateValidRect(col, row, filterRects[index].rc, false); filterRects[index].useFlag = true; } else if( (offsetY + upRc.height) > maxH) { return false; } else { upRc.x = offsetX; upRc.y = offsetY; updateValidRect(col, row, upRc, true); } } else { Rect leftRc = validRects[9*row + col -1].rc; //Align to left and top Rect upRc = validRects[9*(row-1) + col ].rc; int offsetX = upRc.x; int offsetY = leftRc.y; int index = findNearest(leftRc, offsetX, offsetY); //Widht and height can use left or top if(index>0) { updateValidRect(col, row, filterRects[index].rc, false); filterRects[index].useFlag = true; } else if( (offsetX + leftRc.width) > maxW) { return false; } else if( (offsetY + upRc.height) > maxH) { return false; } else { leftRc.x = offsetX; leftRc.y = offsetY; leftRc.width = upRc.width; updateValidRect(col, row, leftRc, true); } } } } } int getVirtualRectsCount() { int count = 0; for(int i = 0; i < 81; i++) { if(validRects[i].virtualFlag == true) count++; } return count; } bool modifyValidRect() { for(int row = 0; row < 9; row++) { for(int col = 0; col < 9; col++) { if(validRects[9*row+col].virtualFlag == false) continue; ValidRect leftRc, upRc, rightRc, bottomRc; bool left, up, right, bottom; left = false; up = false; right = false; bottom = false; if(row != 0) { upRc = validRects[9*(row-1) + col ]; up = true; } if(row != 8) { bottomRc = validRects[9*(row + 1) + col]; bottom = true; } if(col != 0) { leftRc = validRects[9*row + col -1]; left = true; } if(col != 8) { rightRc = validRects[9*row + col + 1]; right = true; } if(left && (leftRc.virtualFlag == false)) { validRects[9*row+col].rc.y = leftRc.rc.y; validRects[9*row+col].rc.height = leftRc.rc.height; } else if(right && (rightRc.virtualFlag == false)) { validRects[9*row+col].rc.y = rightRc.rc.y; validRects[9*row+col].rc.height = rightRc.rc.height; } if(up && (upRc.virtualFlag == false)) { validRects[9*row+col].rc.x = upRc.rc.x; validRects[9*row+col].rc.width = upRc.rc.width; } else if(bottom && (bottomRc.virtualFlag == false)) { validRects[9*row+col].rc.x = bottomRc.rc.x; validRects[9*row+col].rc.width = bottomRc.rc.width; } } } return true; } //int findNearest(Mat& src, int offsetX, int offsetY) //{ // int max_dist = src.size().width * src.size().width + src.size().height * src.size().height; // int index = -1; // // for(unsigned int j = 0; j < stardRect.size(); j ++ ) // { // int dx = stardRect[j].x -offsetX; // int dy = stardRect[j].y -offsetY; // // int dist = dx*dx + dy*dy; // if( dist < max_dist) // { // index = j; // max_dist = dist; // } // } // // if(max_dist < 1800) // return index; // else // return -1; //} // void GetROI(Mat& src, Mat& dst) { int left, right, top, bottom; left = src.cols; right = 0; top = src.rows; bottom = 0; for(int i=0; i<src.rows; i++) { for(int j=0; j<src.cols; j++) { if(src.at<uchar>(i, j) > 0) { if(j<left) left = j; if(j>right) right = j; if(i<top) top = i; if(i>bottom) bottom = i; } } } cv::Point center; center.x = (left + right) / 2; center.y = (top + bottom) / 2; int width = right - left; int height = bottom - top; int len = (width < height) ? height : width; dst = Mat::zeros(len, len, CV_8UC1); cv::Rect dstRect((len - width)/2, (len - height)/2, width, height); cv::Rect srcRect(left, top, width, height); Mat dstROI = dst(dstRect); Mat srcROI = src(srcRect); srcROI.copyTo(dstROI); } //bool findValidRects(Mat& src, double stardWidth, double stardHeight) //{ // int minX, minY, maxX = 0, maxY = 0; // minX = src.cols; // minY = src.rows; // // for(unsigned int j = 0; j < stardRect.size(); j ++ ) // { // if(stardRect[j].x < minX) minX = stardRect[j].x; // if(stardRect[j].x > maxX) maxX = stardRect[j].x; // if(stardRect[j].y < minY) minY = stardRect[j].y; // if(stardRect[j].y > maxY) maxY = stardRect[j].y; // } // // int cols = (maxX - minX) / stardWidth + 0.5; // int rows = (maxY - minY) / stardHeight + 0.5; // // // //Not enough valid rect // if( (cols != 9) || (rows != 9) ) // return false; // // int realWidth = (maxX - minX) / 8; // int realHight = (maxY - minY) / 8; // // for(int row = 0; row<rows; row++) // { // for(int col = 0; col<cols; col++) // { // int offsetX = col * realWidth + minX; // int offsetY = row * realHight + minY; // // int index = findNearest(src, offsetX, offsetY); // int vIndex = col + row *9; // // if(index >= 0) // { // validRects[vIndex].rc = stardRect[index]; // validRects[vIndex].flag = true; // } // else // { // validRects[vIndex].rc = Rect( offsetX, offsetY, stardWidth, stardHeight); // validRects[vIndex].flag = false; // } // validRects[vIndex].col = col; // validRects[vIndex].row = row; // // //Only care about 90% rect(ignore edge noise) // //validRects[vIndex].rc.x = validRects[vIndex].rc.x + validRects[vIndex].rc.width / 10; // //validRects[vIndex].rc.y = validRects[vIndex].rc.y + validRects[vIndex].rc.height / 10; // //validRects[vIndex].rc.width = validRects[vIndex].rc.width / 10 * 9; // //validRects[vIndex].rc.height = validRects[vIndex].rc.height / 10 * 9; // // } // } // // return true; //} // //bool findStardardRect(Mat& dst) //{ // int allCount = rects.size(); // // if(allCount < 81) // return false; // // // read 4 sequence elements at a time (all vertices of a square) // int step = 20; // //int step = 8; // int start1 = 0, start2 = step / 2; // // Mat widths = Mat::zeros(2, dst.cols / step + 1, CV_16UC1); // Mat heights = Mat::zeros(2, dst.rows / step + 1, CV_16UC1); // // int col1, col2, row1, row2; // // for(unsigned int i = 0; i < rects.size(); i ++ ) // { // col1 = rects[i].width / step; // col2 = (rects[i].width - start2) / step; // // row1 = rects[i].height / step; // row2 = (rects[i].height - start2) / step; // // widths.at<short>(0, col1) = widths.at<short>(0, col1) + 1; // widths.at<short>(1, col2) = widths.at<short>(1, col2) + 1; // heights.at<short>(0, row1) = heights.at<short>(0, row1) + 1; // heights.at<short>(1, row2) = heights.at<short>(1, row2) + 1; // // //cv::rectangle(dst, rects[i], CV_RGB(0,255,0)); // } // // double maxCol, maxRow; // // Point pt1, pt2; // // cv::minMaxLoc(widths, 0, &maxCol, 0, &pt1, Mat()); // cv::minMaxLoc(heights, 0, &maxRow, 0, &pt2, Mat()); // // double stardWidth = pt1.x * step + step / 2 + pt1.y * start2; // double stardHeight = pt2.x * step + step / 2 + pt2.y * start2; // // for(unsigned int i = 0; i < rects.size(); i ++ ) // { // if( (abs(rects[i].width - stardWidth) < step / 2) && (abs(rects[i].height - stardHeight) < step / 2 ) ) //Sharp check // { // bool flag = true; // for(unsigned int j = 0; j < stardRect.size(); j ++ ) // { // if( (abs(rects[i].x - stardRect[j].x) < (stardWidth - step / 2)) && (abs(rects[i].y - stardRect[j].y) < (stardHeight - step / 2)) ) // { // flag = false; // break; // } // } // // if(flag) // stardRect.push_back(rects[i]); // } // } // // return findValidRects(dst, stardWidth, stardHeight); //} // void drawAllRect(Mat& dst) { //for(unsigned int i = 0; i < stardRect.size(); i ++ ) // { // cv::rectangle(dst, stardRect[i], CV_RGB(0,255,0)); //} for(unsigned int i = 0; i < allRects.size(); i ++ ) { cv::rectangle(dst, allRects[i], CV_RGB(0,255,128), 5); } } void drawFilterRect(Mat& dst) { //for(unsigned int i = 0; i < stardRect.size(); i ++ ) // { // cv::rectangle(dst, stardRect[i], CV_RGB(0,255,0)); //} for(unsigned int i = 0; i < filterRects.size(); i ++ ) { cv::rectangle(dst, filterRects[i].rc, CV_RGB(255,255,0), 5); } } void drawValidRect(Mat& dst) { //for(unsigned int i = 0; i < stardRect.size(); i ++ ) // { // cv::rectangle(dst, stardRect[i], CV_RGB(0,255,0)); //} for(unsigned int i = 0; i < 81; i ++ ) { if(validRects[i].virtualFlag) cv::rectangle(dst, validRects[i].rc, CV_RGB(0,255,0), 5); else cv::rectangle(dst, validRects[i].rc, CV_RGB(0,0,255), 5); } } void newFindSquares4(Mat& src) { storage = cvCreateMemStorage(0); IplImage* img = &IplImage(src); findSquares4(img, storage); } int getMaxContour(vector<vector<Point>> &contours, double& maxArea) { int index = -1; maxArea = -1; for(unsigned int i=0; i<contours.size(); i++) { double area = cv::contourArea(Mat(contours[i])); if(area>maxArea) { index = i; maxArea = area; } } return index; } void removeBlank(Mat& src) { Mat gray, tempGray; cvtColor(src, gray, CV_RGB2GRAY); cv::pyrDown(gray, tempGray); //, 7 ); cv::pyrUp(tempGray, gray ); //, 7 ); //cv::GaussianBlur(gray, tempGray, cvSize(3,3), 3); //cv::GaussianBlur(tempGray, gray, cvSize(3,3), 3); //medianBlur(gray, tempGray, 1); //medianBlur(tempGray, gray, 1); //dilate(dst, temp, Mat(), Point(-1,-1), 3); //dilate(temp, dst, Mat(), Point(-1,-1), 3); //erode(gray, tempGray, Mat(), Point(-1,-1), 1); //dilate(tempGray, gray, Mat(), Point(-1,-1), 1); //cv::subtract(dst, back, dst, Mat()); //equalizeHist(dst, dst); #if(0) Mat gray2; resize(gray, gray2, cvSize(gray.size().width / 2, gray.size().height / 2)); imshow("gray", gray2); if(waitKey(0) == 27) return; #endif for(unsigned int i = 0; i < 81; i ++ ) { validRects[i].blankFlag = true; //Mat dst, back, temp; Mat dst = gray(validRects[i].rc); float proportion; Scalar contrast; validRects[i].contrast = getBkInfo(dst, proportion, contrast); if(validRects[i].contrast<2) // || proportion>0.95) { //stringstream ss; cout << "No number at " << i << ", contrast " << validRects[i].contrast << endl; continue; } //Make inner ellipse to reduce edge noise Point2f centerPt; centerPt.x = dst.size().width / 2; centerPt.y = dst.size().height / 2; cv::RotatedRect rrc(centerPt, cvSize(dst.size().width, dst.size().height), 0); Mat mask = Mat::zeros(dst.size(), CV_8UC1); cv::ellipse(mask, rrc, Scalar(255,255,255), -1); Mat temp, temp2; temp2 = Mat::zeros(dst.size(), CV_8UC1); double thresh = threshold(dst, temp, 0, 0, CV_THRESH_OTSU); //求出分割閾值 threshold(dst, temp, thresh, 255, CV_THRESH_BINARY_INV); //分割 temp.copyTo(temp2, mask & 1); temp2.copyTo(temp); //if(i==60) //{ // imshow("BIN", temp); // if(waitKey(0) == 27) // break; //} //cv::adaptiveThreshold(dst, temp, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, 5); vector<vector<Point>> contours; vector<Vec4i> hierarchy; #if(0) imshow("ellipse", temp); if(waitKey(0) == 27) break; #endif //Mat mColor = Mat::zeros(temp.size(), CV_8UC3); findContours(temp, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); //CV //findContours(temp, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); //CV Scalar color(0, 255, 255 ); double maxArea = -1; int maxContourIndex = getMaxContour(contours, maxArea); validRects[i].areaProportion = maxArea / validRects[i].rc.area(); if(maxContourIndex < 0) { cout << "No number at " << i << ", no contour find " << endl; continue; } else if(validRects[i].areaProportion < MIN_CONTOUR_PROPORTION) //(validRects[i].rc.area() / 50) ) { cout << "No number at " << i << ", contour area too small, proportion is " << validRects[i].areaProportion << endl; continue; } else { validRects[i].blankFlag = false; validRects[i].contourRc = boundingRect(Mat(contours[maxContourIndex])); //if(validRects[i].contrast > 20) //{ // imshow("ellipse", temp); // if(waitKey(0) == 27) // break; //} } } } void Predict(Mat& src) { char result[81]; memset(result, '-', sizeof(result)); //CvRTrees forest; //forest.load( "D:\\SourceCode\\2011\\CV\\CvChessMove\\SvmClassifierForNum\\new_rtrees_10000.xml" ); int featureLen = 64; CvSVM svm; svm.load( "D:\\SourceCode\\2011\\CV\\CvChessMove\\SvmClassifierForNum\\SVM_DATA_60000.xml" ); RtTrainData rtd; memset(rtd.data, 0, sizeof(rtd.data)); Mat m = Mat::zeros(1, featureLen, CV_32FC1); Mat gray, tempGray; cvtColor(src, gray, CV_RGB2GRAY); #if(0) imshow("gray", gray); if(waitKey(0) == 27) return; #endif for(unsigned int i = 0; i < 81; i ++ ) { Mat dst = gray(validRects[i].rc); if(validRects[i].blankFlag == false) { Mat target, temp; double thresh = threshold(dst, target, 0, 0, CV_THRESH_OTSU); //求出分割閾值 threshold(dst, target, thresh, 255, CV_THRESH_BINARY_INV); //分割 GetROI(target(validRects[i].contourRc), temp); #if(0) imshow("NUM", temp); if(waitKey(0) == 27) break; #endif Mat temp2 = Mat::zeros(8, 8, CV_8UC1); resize(temp, temp2, temp2.size()); for(int i = 0; i<8; i++) { for(int j = 0; j<8; j++) { rtd.data[j + i*8] = temp2.at<uchar>(i, j); //注意m.data為UCHAR*類型,因此m的值不能使用下面的表達式 //m.data[j + i*8] = temp3.at<uchar>(i, j); } } memcpy(m.data, rtd.data, featureLen * sizeof(float)); GetRectFeatures(rtd); //memcpy(m.data, rtd.data, featureLen * sizeof(float)); //result[i] = forest.predict(m); normalize(m, m); float svm_ret = svm.predict(m); char svm_char = (char)svm_ret; cout << svm_char << " at " << i << ", contour proportion " << validRects[i].areaProportion << ", contrast " << validRects[i].contrast << endl; result[i] = svm.predict(m); } } cout << endl << "SUDOKU RESULT: "<< endl; for(int i=0; i<9; i++) { for(int j=0; j<9; j++) cout << result[9*i+j] << '\t'; cout << endl; } } int main(int argc, char** argv) { string fileName = "../../res/sudoku/svg_sudoku7.jpg"; Mat src = imread(fileName, 1); Mat dst; // = Mat::zeros(cvSize(src.size().width / 2, src.size().height / 2), CV_8UC3); //Mat org = imread(fileName, 1); //flip(src, src, -1); //Mat src = Mat::zeros(768, 1024, CV_8UC3); //resize(org, src, src.size()); newFindSquares4(src); filterDupRect(); //drawAllRect(src); //drawFilterRect(src); //resize(src, dst, cvSize(src.size().width / 2, src.size().height / 2)); //imshow("all", src); //waitKey(0); if(findValidRects(src)) { int vc = getVirtualRectsCount(); cout << "Virtual rects count is " << vc << endl; if(vc < 30) { modifyValidRect(); removeBlank(src); Predict(src); } else cout << "Too much virtual rects to continue predict" << endl; } else cout << "Find rects error" << endl; drawValidRect(src); resize(src, dst, cvSize(src.size().width / 2, src.size().height / 2)); imshow("IMG", dst); waitKey(0); return 0; }

?


創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的用OPENCV视觉解数独的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

日韩精品一区二区在线观看视频 | 日韩电影在线观看一区 | 精品欧美乱码久久久久久 | 亚洲综合最新在线 | 亚洲精选99 | 国产剧情av在线播放 | 九九热.com | 成人h动漫精品一区二 | 蜜臀久久99静品久久久久久 | 久久久久一区二区三区 | 在线视频中文字幕一区 | 欧美久久影院 | 久久综合影视 | 丁香五婷| 天天干夜夜想 | 亚洲综合精品在线 | 欧美一级片免费 | 国产自产高清不卡 | 天天激情 | 色狠狠操 | 中文字幕一区二区三区在线视频 | 狠狠的干狠狠的操 | 久久欧美视频 | 一级特黄aaa大片在线观看 | 看片一区二区三区 | 久草在线电影网 | 成人一区二区三区中文字幕 | 免费亚洲婷婷 | 五月丁婷婷 | 成人国产精品免费 | 激情欧美xxxx | av黄色影院 | 免费日韩在线 | 日本69hd| 99九九视频 | 91精品国产综合久久福利 | 精壮的侍卫呻吟h | 狠狠激情中文字幕 | 久章草在线观看 | 欧美一级片免费观看 | 九九九热精品免费视频观看网站 | 日日躁夜夜躁xxxxaaaa | 中文字幕日韩国产 | 日韩电影中文,亚洲精品乱码 | 91黄色在线视频 | 99精品国产99久久久久久福利 | 亚洲天天看 | 日韩在线看片 | 色欧美成人精品a∨在线观看 | 国产 日韩 中文字幕 | 中文字幕亚洲综合久久五月天色无吗'' | 久久久网站 | 精品国产三级 | 欧美日韩激情网 | 麻豆视频免费在线播放 | 91女子私密保健养生少妇 | 精品视频在线观看 | 久草视频观看 | 一二三区高清 | 99久久精品久久久久久清纯 | 99精品国产亚洲 | 国产精品免费麻豆入口 | 亚洲年轻女教师毛茸茸 | 久久综合久色欧美综合狠狠 | 五月婷婷免费 | 精品一区二区6 | 热re99久久精品国产99热 | 99久热在线精品视频成人一区 | 91视频免费看 | 97人人爽人人 | 国产999精品 | 人人澡人人舔 | 91麻豆精品国产自产在线游戏 | 国产免费亚洲高清 | 色综合久久66 | 美女网站在线观看 | 久久国产精品一区二区 | 国产看片网站 | 四虎天堂 | 国产成人99久久亚洲综合精品 | 日本特黄特色aaa大片免费 | 国产三级av在线 | 国产精品网站一区二区三区 | 午夜av剧场| 18久久久久久 | 国产在线中文 | 国产亚洲一区二区三区 | 麻豆国产精品永久免费视频 | 能在线看的av | 免费在线观看一区 | av在线播放快速免费阴 | 国内精品久久久久久久97牛牛 | 精品国产欧美一区二区 | 99久久超碰中文字幕伊人 | 亚洲成人软件 | 91成人观看| 欧美日韩视频免费 | 日本激情视频中文字幕 | 久久久久国产精品免费 | 四虎永久国产精品 | 精品久久久久久久 | 国产成人香蕉 | 亚洲在线色 | 激情网综合 | 中文字幕在线观看免费高清电影 | 国产原创中文在线 | 欧美a级片免费看 | 久热免费在线观看 | 成人在线播放免费观看 | 中文字幕 二区 | 最近免费中文字幕大全高清10 | 日韩午夜av电影 | 国产福利在线不卡 | 成人一区影院 | 精品视频久久久久久 | 免费精品国产 | 日b视频在线观看网址 | 精品产品国产在线不卡 | 日韩在线网 | 99久久久国产精品免费观看 | 99久久婷婷国产综合精品 | 中文字幕在线观看你懂的 | 97人人视频 | 国产一区二区精品久久91 | 中文字幕免费在线看 | 丁香花中文字幕 | 91在线免费公开视频 | 久久国产三级 | 国产97色 | 亚洲欧洲精品久久 | 中文在线www | av一区在线播放 | 玖玖视频在线 | 国产日韩在线视频 | 国产女人40精品一区毛片视频 | 国产福利精品一区二区 | 91九色蝌蚪| 成人精品99 | 中文字幕在线视频免费播放 | av成人亚洲 | 欧美成人精品欧美一级乱黄 | 婷婷丁香激情综合 | 欧美另类老妇 | 丁香亚洲| av大片免费看 | 国产91在线观 | 国产高清黄 | 中文字幕在线观看一区二区 | 亚洲第一香蕉视频 | 久久私人影院 | 国产精品午夜在线观看 | 91九色国产在线 | 在线不卡视频 | 99视频精品视频高清免费 | 久久超碰网 | 丁香激情综合国产 | 欧美视频国产视频 | 国产成人高清 | 伊人色播 | 色丁香综合 | 国产中文欧美日韩在线 | 五月天色中色 | 午夜精品久久久久久久久久久 | 免费看的黄色的网站 | 久久久久久久av | 久久精品视频免费 | 国产精在线 | 欧美色图一区 | 久久夜夜爽 | 久久xx视频 | 免费a网 | 在线观看国产亚洲 | 日韩欧美在线观看 | www日韩在线| 精品国产伦一区二区三区观看说明 | 日韩欧美黄色网址 | 国产亚洲在线视频 | 国产精品久久久久一区二区 | 免费能看的黄色片 | 国产成人61精品免费看片 | 久久国产剧场电影 | 国产精品成人久久久久久久 | 国产黄色高清 | 视频国产在线 | 狠狠躁日日躁夜夜躁av | 一区二区三区四区免费视频 | 国产一级片网站 | 日本精品在线看 | 中文字幕不卡在线88 | 超碰九九| 国产美女精品视频免费观看 | 激情九九 | 日本中文字幕视频 | 久久这里只精品 | 成人av在线影院 | 看片在线亚洲 | 伊人精品在线 | 国产视频一区二区在线 | 天天爽天天射 | 久久视频这里有精品 | 国产91免费在线 | 国产精品福利在线播放 | 欧美激情精品久久久久久变态 | 久久视频在线观看免费 | 日韩a欧美 | 国产一级片在线播放 | 日韩在观看线 | 日韩免费观看视频 | 国产一区在线免费观看视频 | 国产亚洲在线 | 香蕉视频在线观看免费 | 2022国产精品视频 | 欧美午夜久久久 | 91久久久久久久一区二区 | 久久精品女人毛片国产 | 一区二区三区 中文字幕 | 九九九九九国产 | 日韩字幕 | 毛片在线播放网址 | 国产一区 在线播放 | av韩国在线 | av亚洲产国偷v产偷v自拍小说 | 久久精品一二区 | 色a在线观看 | 久久成人精品视频 | 国内精品久久久精品电影院 | 在线观看av国产 | 欧美日韩国内在线 | av在线亚洲天堂 | 日韩在线免费视频 | 一二三区av | 91精品国产九九九久久久亚洲 | 久久人人爽人人爽人人片av免费 | 欧美成年人在线观看 | 三级av免费观看 | 国产一区欧美在线 | 伊人黄 | 色干干 | 91资源在线免费观看 | 久久美女精品 | 丁香激情网 | 久久人人爽视频 | 四虎在线观看视频 | 免费看三片 | 人人干人人爽 | 久久精品亚洲一区二区三区观看模式 | 91在线区 | 天天曰天天射 | 国产成人亚洲精品自产在线 | 99理论片| 国产午夜精品一区二区三区在线观看 | 欧美二区在线播放 | 成人国产精品免费 | 日日草天天干 | 欧美成人性战久久 | 久久久91精品国产一区二区三区 | 91精品国产91久久久久福利 | 国产精品日韩欧美一区二区 | 精品中文字幕视频 | 免费高清在线视频一区· | 亚洲欧美国产日韩在线观看 | 国产精品人成电影在线观看 | 91福利视频免费 | 国产精品久久久久久一区二区 | 日韩首页| 亚洲精品大片www | 69精品人人人人 | 久久不射电影网 | 国产精品成人久久久久久久 | 久久黄视频 | 国产精品午夜在线 | 91视频在线观看免费 | 午夜视频在线瓜伦 | 久久欧美综合 | 五月婷婷开心 | 国产综合片 | 国产精品一区电影 | 国产精品成人av电影 | 中文字幕在线观看三区 | 夜夜躁日日躁狠狠躁 | 国产一级大片在线观看 | 黄色一级网 | 日韩欧美大片免费观看 | 色国产在线 | 激情五月婷婷丁香 | 超碰官网 | 免费成人看片 | 99精品国产兔费观看久久99 | 欧美日韩国产伦理 | 996久久国产精品线观看 | 天天天天天天操 | 青青河边草免费直播 | 精品一区二区在线免费观看 | 色天天综合久久久久综合片 | 日本精品一区二区在线观看 | 色激情五月| 国产成人在线免费观看 | 欧美精品中文在线免费观看 | 午夜精品一区二区三区可下载 | 亚洲人成人99网站 | 亚洲精品日韩在线观看 | 99久久精品费精品 | 最新av免费在线 | 国产精品国产三级国产专区53 | 色综合久久久久综合99 | 久久神马影院 | 国产精品亚洲综合久久 | 成人黄色影片在线 | 中文字幕在线观看1 | 在线观看国产 | 国产精品入口麻豆 | 国产色小视频 | 天天操天天操一操 | 亚洲va在线va天堂va偷拍 | 又紧又大又爽精品一区二区 | 日韩在线理论 | 久久综合久久综合这里只有精品 | 探花视频在线版播放免费观看 | 亚洲精品国产精品久久99热 | 在线观看日韩精品视频 | 久久精品欧美一区 | 亚洲一区视频免费观看 | 欧美一区免费在线观看 | 水蜜桃亚洲一二三四在线 | 亚洲精品乱码久久久久久蜜桃欧美 | 久久久久久蜜桃一区二区 | 色综久久 | 久久99精品热在线观看 | 精品视频久久久 | 国产黄色精品视频 | 91精品久久久久久久久久入口 | 特级黄录像视频 | 欧美日韩国产色综合一二三四 | 伊人五月在线 | 国产成人黄色网址 | 欧美久久九九 | 久久精品一区二区三区国产主播 | 91激情在线视频 | 久久tv| 视频二区 | 国产成人久久精品一区二区三区 | 国产午夜精品一区二区三区嫩草 | 99久久这里有精品 | 深夜免费福利 | 香蕉视频久久 | 日韩毛片在线免费观看 | 日日干激情五月 | 精品色999| 成人国产精品入口 | 99这里只有精品视频 | 精品国自产在线观看 | 日韩久久精品一区二区 | 一级淫片在线观看 | 久久激情片 | 欧美另类tv | 婷婷丁香视频 | 99精品福利视频 | 亚洲国产精品va在线看黑人 | www.久久久精品 | 丁香花在线观看视频在线 | 国产精品h在线观看 | 欧美精品v国产精品v日韩精品 | av在线等 | 久久婷婷精品视频 | 国产原创在线 | 黄色视屏免费在线观看 | 丁香婷婷激情五月 | 亚洲综合小说电影qvod | 精品国产伦一区二区三区观看体验 | www色网站 | 成年人视频在线 | 在线欧美中文字幕 | 国产精品综合久久久久 | 久久电影中文字幕视频 | 成人一区二区三区在线观看 | 日韩在线视频国产 | 婷婷九九| 亚洲国产天堂av | 九色精品在线 | av性网站 | 亚洲成人av在线电影 | 成人av日韩 | a在线观看免费视频 | 在线观看视频精品 | 麻豆视频大全 | 免费手机黄色网址 | 亚洲最大av| 丁香婷婷亚洲 | 色婷婷av一区 | 中文字幕av免费 | 欧美久久久久久久久中文字幕 | 久久综合免费视频 | 色婷婷婷 | 亚洲精品久久久久中文字幕二区 | 国产激情电影综合在线看 | 91网址在线观看 | 亚洲成人高清在线 | 成人精品一区二区三区电影免费 | 婷婷亚洲综合 | 国产福利av | 免费福利片2019潦草影视午夜 | 成人小视频免费在线观看 | 亚洲精品在线视频观看 | 香蕉视频网站在线观看 | 成人av播放| 中文字幕在线视频第一页 | 婷婷99| 久久神马影院 | 久久婷婷五月综合色丁香 | 国产 字幕 制服 中文 在线 | 视频1区2区 | 色综合久久久久综合99 | 日韩欧美一区二区三区在线观看 | 亚洲精品视频网址 | 99综合影院在线 | 97综合在线| 欧美在线1 | 精品国产91亚洲一区二区三区www | 亚洲黄色在线播放 | 麻豆国产视频 | 免费国产在线视频 | 99久久久国产免费 | 久久精品久久精品久久 | 正在播放一区二区 | 蜜臀久久99精品久久久无需会员 | 久久婷婷一区二区三区 | 婷婷色六月天 | 国内精品久久久久影院优 | 久久免费影院 | 中文字幕免费播放 | 久久久久在线视频 | 欧美一级电影片 | 国产一线天在线观看 | 久久综合免费视频 | 色999在线 | 日韩欧美一区二区三区黑寡妇 | 亚洲精品国产成人av在线 | 亚洲美女视频在线观看 | 久久视频精品 | 99精品视频在线观看免费 | www.色就是色| 在线观看黄网 | 丁香五婷| 97热视频| 超碰在线观看av | 超碰久热 | 亚洲成人网在线 | 国内精品视频在线 | 精品久久网站 | 欧美精品一二三 | 91精品国产99久久久久 | 国产精品久久久久影院日本 | 久草免费资源 | 久久精品久久久久电影 | 中文字幕在线国产精品 | 国产91九色视频 | 在线黄色免费 | 国产精品电影在线 | 久久综合狠狠综合久久综合88 | 久久久久久国产精品亚洲78 | 久久久久看片 | 麻豆免费精品视频 | 久久经典国产 | 亚洲专区免费观看 | 国产黄色片免费观看 | www.色在线| 色视频在线免费观看 | 亚洲国产97在线精品一区 | 精品久久久成人 | 久草在线视频首页 | 国产破处在线视频 | 日韩在线观看的 | 日韩在线网址 | 久草在线最新视频 | 特级西西www44高清大胆图片 | 国产又粗又猛又爽又黄的视频先 | 最近在线中文字幕 | 日韩最新在线 | 嫩小bbbb摸bbb摸bbb | 五月天综合色激情 | av一级二级| 成人羞羞视频在线观看免费 | 欧美国产日韩一区二区三区 | 成人免费中文字幕 | 国产专区欧美专区 | 欧美精品v国产精品v日韩精品 | 国产成人99久久亚洲综合精品 | 黄色网址av | 特级西西444www大胆高清无视频 | 欧美精品九九99久久 | 国产亚洲精品中文字幕 | 免费视频一区 | 狂野欧美激情性xxxx欧美 | 免费看v片 | 91看片淫黄大片一级在线观看 | 久久国语| 日日躁你夜夜躁你av蜜 | 高清av网站 | 99久久久成人国产精品 | 久久一区二区三区日韩 | 国产精品美女视频 | 狠狠天天 | 少妇性色午夜淫片aaaze | 久久久999免费视频 日韩网站在线 | 成人午夜在线电影 | 伊人一级| 国产一区精品在线 | 欧美一二三专区 | 国产精品一区二区你懂的 | 成x99人av在线www | 国产亚洲精品久久19p | 亚洲三级黄色 | 日韩国产精品毛片 | 久久精品国产免费 | 久久精品这里热有精品 | 亚洲精品乱码久久久久久久久久 | 五月天色中色 | 亚洲精选在线 | 99久久精品电影 | 伊人国产视频 | 国产成人在线免费观看 | 波多野结衣在线视频免费观看 | 98涩涩国产露脸精品国产网 | 成 人 免费 黄 色 视频 | 亚洲国产大片 | 亚洲综合色视频 | 黄网站免费久久 | 91av官网 | 懂色av懂色av粉嫩av分享吧 | 999久久久久 | 亚洲综合网 | 婷婷精品视频 | 黄a网| 久草综合视频 | 手机在线小视频 | 成人在线视频免费看 | 中文字幕一区二区三 | 五月激情站 | 久草在线免费看视频 | 91麻豆国产福利在线观看 | 久久精品一区 | 欧美激情综合五月色丁香小说 | 中文字幕精品一区久久久久 | 婷婷色综 | 亚洲成av人片在线观看www | 黄色网址在线播放 | 天天摸天天舔 | 97免费在线视频 | 激情五月在线视频 | 欧美极品xxx | 欧美成人亚洲成人 | 精品免费一区 | 四虎国产精品免费 | 欧美一区二区三区激情视频 | 国产91精品看黄网站 | 91| 337p日本欧洲亚洲大胆裸体艺术 | 黄色视屏免费在线观看 | 成人在线免费视频 | 久久综合久久伊人 | 91麻豆精品国产91久久久更新时间 | 久久精品99国产国产精 | 久久不卡国产精品一区二区 | 在线观看av黄色 | 国产一区二区三区免费观看视频 | 久久综合五月 | 69精品人人人人 | 久久女同性恋中文字幕 | 亚洲少妇激情 | 亚洲a网| 亚洲一区二区三区91 | 人人爽人人片 | 最新国产在线 | 丁香六月婷婷开心 | 91精品亚洲影视在线观看 | 免费v片| 亚洲国产精品视频在线观看 | 亚洲国产高清在线观看视频 | 三级黄免费看 | 国产欧美在线一区二区三区 | www.久久免费 | 国产午夜精品一区二区三区嫩草 | 亚洲色图av| 亚洲一级影院 | 国产免费一区二区三区最新6 | 欧美乱淫视频 | 色999视频| 亚洲婷婷伊人 | 国产亚洲精品bv在线观看 | 色婷婷成人 | 久久精品国产成人精品 | 国产精品一区二区久久久 | 免费看成年人 | 久久亚洲婷婷 | 中文在线8资源库 | 午夜精品成人一区二区三区 | 午夜123| 婷婷综合网 | 国产不卡一二三区 | 五月天精品视频 | 成人播放器 | 色欧美视频 | 欧美精品v国产精品 | 国产91精品看黄网站在线观看动漫 | 97超碰中文字幕 | 色吊丝在线永久观看最新版本 | 成人免费大片黄在线播放 | 在线播放精品一区二区三区 | 婷婷色在线视频 | 亚洲成人精品影院 | 日韩一区二区三区免费电影 | 又黄又爽的视频在线观看网站 | 午夜视频在线瓜伦 | 91精品少妇偷拍99 | 国产成人福利在线观看 | 中文字幕一区二区三区乱码在线 | 久久伊人热 | 成年美女黄网站色大片免费看 | 久久国产精品一二三区 | 亚洲人xxx | 国产久草在线 | 337p日本大胆噜噜噜噜 | 免费观看mv大片高清 | 91视频啪 | 97在线视频免费观看 | 在线观看一级 | 国产精品入口a级 | 久久av网址 | 久热色超碰 | 不卡电影一区二区三区 | 97精品国产91久久久久久 | 天堂网av在线 | 欧美精品网站 | av福利超碰网站 | 婷婷在线色| 午夜精品三区 | 黄色片免费在线 | 国产成人精品一区二区在线 | 国产中文自拍 | 免费欧美 | 高潮久久久久久 | 精品欧美一区二区三区久久久 | 久久久久久久久久久久av | 亚洲高清视频一区二区三区 | 日韩一区精品 | 国产美女网 | 欧美做受高潮 | 一级a毛片高清视频 | 午夜在线观看一区 | 免费精品视频在线 | 在线观看国产日韩欧美 | 日韩高清激情 | 一区二区三区四区免费视频 | 在线观看成人一级片 | 国产精品视频免费看 | 久久免费国产视频 | 久久99精品久久久久久三级 | 亚洲伦理一区二区 | 久久综合丁香 | 福利一区二区三区四区 | 国产精品18久久久久久久久久久久 | 伊人久久精品久久亚洲一区 | 国产99久久精品一区二区永久免费 | 精品视频97 | 国产精品美女久久久久久免费 | 国产视频91在线 | 成人毛片网| 激情综合婷婷 | 高清av在线免费观看 | av中文电影 | 五月天婷婷免费视频 | 超碰国产在线 | 亚洲成色777777在线观看影院 | 人人爽人人做 | 97成人免费| 狠狠干成人综合网 | 日韩电影在线一区二区 | 一级片在线 | 99精品免费视频 | 丁香视频全集免费观看 | 国产精品欧美久久 | 欧美一区二区在线免费看 | 亚洲一级特黄 | 黄污在线看 | 久久1电影院| 久久看视频 | 麻豆视频观看 | 国产人成精品一区二区三 | 日本韩国精品一区二区在线观看 | 免费高清国产 | 黄色av电影免费观看 | va视频在线 | 免费看国产a | 国内外成人在线 | 日韩久久精品一区二区三区 | 一区二区精品国产 | 国产97色 | 天天天在线综合网 | 狠狠的操狠狠的干 | 国产中文字幕在线观看 | 精品久久久久久亚洲综合网站 | 亚洲精品视频免费在线观看 | 97人人看 | 美女视频一区二区 | 91中文字幕在线视频 | 久久久99精品免费观看app | 麻豆视传媒官网免费观看 | 在线观看黄网站 | 国产精品资源网 | 国产91影院 | 色天天综合久久久久综合片 | 不卡av在线 | 国产中文字幕在线看 | 日韩在线资源 | 国产精品网站一区二区三区 | 久久男人中文字幕资源站 | 五月综合婷 | 亚洲天堂在线观看完整版 | 手机看片久久 | 日韩高清成人在线 | 91福利国产在线观看 | 免费观看高清 | 午夜久久久精品 | 黄色网免费 | 夜夜躁天天躁很躁波 | 99久久久国产免费 | 久久婷婷综合激情 | 91精品视频免费观看 | 日韩av中文字幕在线免费观看 | www·22com天天操 | 亚洲成人中文在线 | 丁香综合 | 国产成人精品综合久久久 | 国产免费叼嘿网站免费 | 国产手机av| 国产福利精品一区二区 | 欧美一区二区视频97 | 久久久99精品免费观看乱色 | 国产中文字幕在线看 | 精品在线小视频 | 天天操天天爱天天干 | 99精品视频免费观看 | 免费观看的av网站 | 亚洲欧洲精品在线 | 色综合网在线 | 国产精品人人做人人爽人人添 | 久久字幕精品一区 | 欧美综合国产 | 国产精品美女999 | 91视频高清 | 日日夜夜噜 | 99情趣网视频 | 在线观看免费高清视频大全追剧 | 一级片黄色片网站 | 日韩精品一区二区三区在线视频 | 国产一级片在线播放 | 亚洲精品乱码久久久久久蜜桃欧美 | 99久久99久久精品国产片果冰 | 久99热| 久久综合精品一区 | 午夜999| 97天堂网 | 亚洲激情 欧美激情 | 97超碰人人在线 | 亚洲无毛专区 | 国产成人久久精品亚洲 | 亚洲激情六月 | 一级国产视频 | 久久尤物电影视频在线观看 | 欧美性受极品xxxx喷水 | 久久成人午夜 | 五月天精品视频 | 日本特黄特色aaa大片免费 | 国产精品ⅴa有声小说 | 成人三级网站在线观看 | 在线精品视频免费播放 | 婷婷丁香激情网 | 国产精品一区二区在线播放 | 国产精品大片在线观看 | 亚洲乱码国产乱码精品天美传媒 | 四虎永久视频 | 日本xxxx裸体xxxx17 | 波多野结衣电影一区二区 | 国产高清专区 | a视频免费在线观看 | 国产精品久久久久久久av电影 | 欧美精品乱码久久久久久按摩 | 亚洲国产影院av久久久久 | 久久69精品| 深爱激情综合 | 久久视频在线观看 | 一区二区精品国产 | 黄色aaa级片 | 911精品视频 | 成人免费网站视频 | 午夜色影院 | 97超碰.com| 免费看十八岁美女 | 国产一区成人在线 | 亚洲日本色 | 日韩激情片在线观看 | 91中文字幕视频 | 久久综合九色综合欧美狠狠 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | www在线免费观看 | 九九99视频 | 欧美午夜性 | 国产一区二区在线影院 | 蜜臀av一区 | 成人精品久久久 | 亚洲精品视频在线免费播放 | 日韩欧美综合精品 | 97免费公开视频 | 狠狠狠色丁香婷婷综合久久88 | 日韩亚洲在线视频 | 日日夜夜操操操操 | 久久久久久电影 | 黄色www在线观看 | 国产黄色精品 | 久久九九久久精品 | 日日爱视频| 911免费视频 | 天天拍天天草 | 国产精品乱码久久久久 | 国产精品成人国产乱 | 日韩在线精品一区 | 亚洲精品在线电影 | 91成人免费在线 | 国产亚洲aⅴaaaaaa毛片 | 欧美日产在线观看 | 丁香5月婷婷 | 五月激情六月丁香 | 99久久精品国产一区 | 欧美va天堂va视频va在线 | 国产日韩视频在线观看 | 亚洲成年片 | 91精品啪啪 | 婷婷激情久久 | 91视频免费国产 | 欧美一级电影 | 国产人成看黄久久久久久久久 | 天天色天天射天天综合网 | 国产高清不卡一区二区三区 | 午夜精品一区二区三区四区 | 91免费网站在线观看 | 欧美精彩视频 | free,性欧美| 久久久免费精品国产一区二区 | 一区二区三区免费在线观看视频 | www.91国产 | 香蕉视频在线观看免费 | 中文字幕网站视频在线 | 国产一区二区久久久 | 日韩啪视频 | 国产福利不卡视频 | 中日韩在线| 国产小视频免费在线网址 | 国产亚洲情侣一区二区无 | 日韩三级.com | 国产黄色片网站 | 精品国产精品国产偷麻豆 | 人人玩人人添人人澡97 | 黄色在线免费观看网站 | 亚洲精品中文字幕在线观看 | 久草av在线播放 | 中文字幕日本电影 | 西西大胆免费视频 | 在线免费观看一区二区三区 | 久久久久国产精品www | 欧美性生活小视频 | 91最新地址永久入口 | 欧美激情在线看 | 五月的婷婷| 国产高清永久免费 | 欧美另类人妖 | 永久免费观看视频 | 激情五月播播久久久精品 | 91麻豆文化传媒在线观看 | 久久试看 | 亚洲激情一区二区三区 | 成人在线超碰 | 久久艹久久 | 亚洲欧美经典 | 欧美精品久久久久久久久久 | 黄色av成人在线观看 | 日韩毛片精品 | 91黄色在线观看 | 天天操综 | 日韩美女久久 | 99精品亚洲 | 韩日电影在线观看 | 麻豆传媒视频在线 | 久久视频免费看 | 日日天天干 | 国产黄a三级三级三级三级三级 | 视色网站| 日韩毛片一区 | 国产精品手机播放 | 九九久久久久久久久激情 | 中文字幕日韩av | 成人av在线播放网站 | 日韩精品在线视频免费观看 | 亚洲色图 校园春色 | 日日夜夜精品网站 | 91免费观看视频在线 | 日b视频在线观看网址 | 激情中文字幕 | 国产高清av免费在线观看 | 日韩精品高清不卡 | 亚洲黄色免费电影 | 五月婷婷丁香综合 | a黄色片 | 91视频一8mav | www五月| 国产精品久久久久久久久久久不卡 | 亚洲精品视频免费 | 国产黄色资源 | 99色在线播放 | 九九99靖品 | 日韩久久影院 | 狠狠狠狠狠狠干 | 日韩av高潮| 欧美在线视频一区二区三区 | 国产91勾搭技师精品 | 色多多在线观看 | 国产精品免费一区二区三区 | 人人干人人干人人干 | 4438全国亚洲精品在线观看视频 | 国产一区免费视频 | www.夜夜草 | 久久精品第一页 | 97在线精品 | 亚洲高清视频一区二区三区 | 成年人电影免费看 | 精品久久久久久综合 | 精品视频免费在线 | 西西人体4444www高清视频 | 亚洲免费成人av电影 | 在线免费精品视频 | 在线观看视频你懂 | 精品国模一区二区 | 欧美精品亚洲精品日韩精品 | 女女av在线 | 国产亚洲欧美在线视频 | 99久久99久久精品免费 | 国产视频二 | 国产四虎在线 | 91九色视频在线播放 | 亚洲精品乱码久久久久久 | 人人插人人干 | 日韩精品免费一区二区在线观看 | 亚洲精品视频在 | 91在线免费看片 | 国产剧情一区二区在线观看 | 中文字幕免费观看 | 中文字幕 国产精品 | 欧美日韩在线观看一区 | 国产一二区视频 | 成人精品国产 | 欧洲精品码一区二区三区免费看 | 日韩免费看 | 亚洲播放一区 | 久久天天躁狠狠躁亚洲综合公司 | 久久精品5| 97视频在线观看播放 | 黄色在线观看网站 | 六月婷婷久香在线视频 | 欧美激情视频免费看 | 午夜视频亚洲 | 97精品在线 | 久久婷婷精品 | 欧美在线一二 | 欧美性色19p | 97在线视频观看 | 国产男女无遮挡猛进猛出在线观看 | 久久人人爽人人爽人人片 | caobi视频 | 91精品在线视频观看 | 一级免费黄色 | 国产黄a三级三级 | 免费a v观看| 在线看中文字幕 | 中文字幕日本在线观看 | 麻豆国产视频 | 亚洲香蕉视频 | 99精品国产福利在线观看免费 | 2019中文最近的2019中文在线 | 99在线观看视频 | 9色在线视频| 超碰人人91| 国产美女永久免费 | 99精品欧美一区二区蜜桃免费 | 国产又黄又爽又猛视频日本 | 免费成人短视频 | 国产精品视频地址 | 天天综合婷婷 | 亚洲 中文 欧美 日韩vr 在线 | 在线а√天堂中文官网 |