opencv如何用鼠标事件不规则地选择图像区域? C / C ++

时间:2017-02-12 17:16:33

标签: c++ opencv

我最近在学习opencv。有没有办法使用鼠标事件选择图像区域?我已经尝试过三角形了。如果我想选择特定区域而不是三角形,该怎么办?谢谢!

1 个答案:

答案 0 :(得分:2)

我有一点尝试 - 它可能不是最干净的代码,但应该给你一些想法。

org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://graph.facebook.com/v2.8/me": java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext); nested exception is java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:633)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:595)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:328)
{....}
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:280)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
{....}
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
{....}
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:614)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:958)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:452)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2517)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2506)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run

enter image description here

回调说明

#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; // Globals bool finished=false; Mat img,ROI; vector<Point> vertices; void CallBackFunc(int event,int x,int y,int flags,void* userdata) { if(event==EVENT_RBUTTONDOWN){ cout << "Right mouse button clicked at (" << x << ", " << y << ")" << endl; if(vertices.size()<2){ cout << "You need a minimum of three points!" << endl; return; } // Close polygon line(img,vertices[vertices.size()-1],vertices[0],Scalar(0,0,0)); // Mask is black with white where our ROI is Mat mask= Mat::zeros(img.rows,img.cols,CV_8UC1); vector<vector<Point>> pts{vertices}; fillPoly(mask,pts,Scalar(255,255,255)); img.copyTo(ROI,mask); finished=true; return; } if(event==EVENT_LBUTTONDOWN){ cout << "Left mouse button clicked at (" << x << ", " << y << ")" << endl; if(vertices.size()==0){ // First click - just draw point img.at<Vec3b>(x,y)=Vec3b(255,0,0); } else { // Second, or later click, draw line to previous vertex line(img,Point(x,y),vertices[vertices.size()-1],Scalar(0,0,0)); } vertices.push_back(Point(x,y)); return; } } int main() { // Read image from file img=imread("demo.jpg"); // Check it loaded if(img.empty()) { cout << "Error loading the image" << endl; exit(1); } //Create a window namedWindow("ImageDisplay",1); // Register a mouse callback setMouseCallback("ImageDisplay",CallBackFunc,nullptr); // Main loop while(!finished){ imshow("ImageDisplay",img); waitKey(50); } // Show results namedWindow("Result",1); imshow("Result",ROI); waitKey(5000); } 开始时我这样做:

main()

并告诉 OpenCV 在鼠标移动或点击时为我们调用函数setMouseCallback("ImageDisplay",CallBackFunc,nullptr);

CallBackFunc()只是一个普通的函数,就像任何其他函数一样。但是,我们不能自己调用​​它 - OpenCV 异步调用它(当我们不期待它时)。因此,我们无法从函数中看到任何返回值 - 因为我们从未调用它 - 这就是为什么它被声明为:

CallBackFunc()

因为它没有返回任何东西,或者是虚空,或者是虚无的虚空。

好的,让我们继续调用它所调用的参数。基本上,当 OpenCV 的设计者编写void CallBackFunc(...) 函数时,他们无法知道我想要传递给它的参数 - 也许我想传递一个文件名,也许我想在单击鼠标时传递一个文本字符串在图像上绘制,也许我想传递一个我想用鼠标位置更新的变量。它可能是任何东西。因此,正如他们不知道的那样,他们决定说它是&#34;指向任何东西的指针&#34; 我可以将它用于我喜欢的任何地方。好吧,什么都没有,所以指向void的指针可以指向任何东西。所以,他们说只是传递一个指向void的指针,你知道它的含义。然后,在setMouseCallback()内,您可以将指针投射到您传递的任何内容,因为您知道它是什么。

因此,总而言之,指向void的指针只是指向某事物的指针的位置标记,如果没有设计者需要知道的 OpenCV ,您可以决定是什么。

希望有所帮助!