Thông thường, Hough transform được sử dụng để phát hiện dòng.
Nhưng nếu nó không hoạt động cho bạn, đường phù hợp cũng là một lựa chọn tốt.
Kiểm tra OpenCV fitline chức năng để biết thêm chi tiết và thông số.
Vì bạn đã thử dòng hough, tôi sẽ chứng minh dòng phù hợp ở đây, sử dụng OpenCV-Python:
# Load image, convert to grayscale, threshold and find contours
img = cv2.imread('lail.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hier = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
# then apply fitline() function
[vx,vy,x,y] = cv2.fitLine(cnt,cv2.cv.CV_DIST_L2,0,0.01,0.01)
# Now find two extreme points on the line to draw line
lefty = int((-x*vy/vx) + y)
righty = int(((gray.shape[1]-x)*vy/vx)+y)
#Finally draw the line
cv2.line(img,(gray.shape[1]-1,righty),(0,lefty),255,2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Dưới đây là kết quả tôi nhận:
CHỈNH SỬA:
Nếu bạn muốn tìm dòng để chia đối tượng thành hai phần, trước tiên hãy tìm đường phù hợp, sau đó tìm dòng bình thường với nó.
Cho rằng, thêm bên dưới đoạn mã dưới cv2.fitLine() chức năng:
nx,ny = 1,-vx/vy
mag = np.sqrt((1+ny**2))
vx,vy = nx/mag,ny/mag
Và dưới đây là những kết quả tôi nhận:
Hope nó giúp !!!
UPDATE:
Dưới đây là C++ mã cho Python mã của trường hợp đầu tiên như bạn yêu cầu. Mã hoạt động tốt cho tôi. Đầu ra là giống như đưa ra ở trên:
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv/cv.h>
using namespace std;
using namespace cv;
int main()
{
cv::Mat img, gray,thresh;
vector<vector<Point>> contours;
Vec4f lines;
img = cv::imread("line.png");
cv::cvtColor(img,gray,cv::COLOR_BGR2GRAY);
cv::threshold(gray,thresh,127,255,cv::THRESH_BINARY);
cv::findContours(thresh,contours,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE);
cv::fitLine(Mat(contours[0]),lines,2,0,0.01,0.01);
//lefty = int((-x*vy/vx) + y)
//righty = int(((gray.shape[1]-x)*vy/vx)+y)
int lefty = (-lines[2]*lines[1]/lines[0])+lines[3];
int righty = ((gray.cols-lines[2])*lines[1]/lines[0])+lines[3];
cv::line(img,Point(gray.cols-1,righty),Point(0,lefty),Scalar(255,0,0),2);
cv::imshow("img",img);
cv::waitKey(0);
cv::destroyAllWindows();
}
Cảm ơn bạn rất nhiều, tôi sẽ cố gắng ngày hôm nay: D Ồ, tôi là một fan hâm mộ của blog của bạn :) –
Bạn có bất cứ phiên bản dành cho C++? : P –
Xin chào, tất cả các chức năng đều là các chức năng tiêu chuẩn từ OpenCV. Vì vậy, nếu bạn kiểm tra các tài liệu opencv, bạn có thể tìm thấy các hàm C++ tương ứng cho mọi hàm python mà tôi đã sử dụng. Hãy thử nó cho mình, và nếu bạn tìm thấy bất kỳ khó khăn, bình luận cho tôi. Tôi sẽ cố gắng giúp đỡ ... –