我一直在尝试使用OpenCV的MSER算法的Python实现(opencv 2.4.11)和Java实现(opencv 2.4.10).有趣的是,我注意到MSER的detect在Python和Java中返回不同类型的输出.在Python中,detect返回一个点列表列表,其中每个点列表代表一个检测到的blob.在Java中,Mat返回a,其中每行是单个点,其相关直径表示检测到的blob.我想重现Java中的Python行为,其中blob由一组点定义,而不是一个点.有谁知道发生了什么?
蟒蛇:
frame = cv2.imread('test.jpg')
mser = cv2.MSER(**dict((k, kw[k]) for k in MSER_KEYS))
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
regions = mser.detect(gray, None)
print("REGIONS ARE: " + str(regions))
where the dict given to cv2.MSER is
{'_delta':7, '_min_area': 2000, '_max_area': 20000, '_max_variation': .25, '_min_diversity': .2, '_max_evolution': 200, '_area_threshold': 1.01, '_min_margin': .003, '_edge_blur_size': 5}
Run Code Online (Sandbox Code Playgroud)
Python输出:
REGIONS ARE: [array([[197, 58],
[197, 59],
[197, 60],
...,
[143, 75],
[167, 86],
[172, 98]], dtype=int32), array([[114, 2],
[114, 1],
[114, 0],
...,
[144, 56], …Run Code Online (Sandbox Code Playgroud) 简而言之,我正在编写一个应用程序,它需要一个BlockingQueue提供FIFO添加/删除的实现,但也是一种快速contains方法,因为我将其称为TON.
LinkedBlockingQueue让我最那里的方式,但现在看来,它的contains方法以线性时间运行,因为它是基于AbstractQueue的contains方法.我没有在Java API中看到任何似乎用快速contains开箱即用来宣传LBQ的东西.
让事情变得更加艰难的是,我的项目处于非常严峻的时间紧迫状态(不,这不是家庭作业).我可以做一个快速而肮脏的LBQ扩展,HashSet下面有一个快速的contains,但我仍然需要测试它,这可能会耗费大量的工时.我想知道是否有任何受信任/经过良好测试的库提供了LinkedBlockingQueue一个contains在O(1)时间内运行的方法的扩展......?如果没有,欢迎任何其他建议.
总而言之,在我的应用程序不再需要RMI之后,我无法让几个Java RMI的非守护程序线程关闭.这可以防止JVM在main()完成时退出.
我知道导出UnicastRemoteObjects会导致RMI在成功调用之前保持线程处于打开状态UnicastRemoteObject.unexportObject(Object o,boolean force).这是一个示例(无需修改即可运行,JVM将正常退出 - 删除对unexportObject的调用,JVM永远不会退出):
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class TestUnicastRemoteObject{
private static UnicastRemoteObject obj;
private static Registry registry;
public static void main(String[] args) throws Exception{
obj = new UnicastRemoteObject(){
private static final long serialVersionUID = 1L;
};
System.err.println("created UnicastRemoteObject");
System.err.println("creating registry ...");
registry = LocateRegistry.createRegistry(9999);
System.err.println("registry created.");
System.err.println("binding obj to registry ...");
registry.bind("Test", obj);
System.err.println("bound");
UnicastRemoteObject.unexportObject(obj, true);
System.err.println("unexported obj");
}
}
Run Code Online (Sandbox Code Playgroud)
此外,您是否创建注册表和/或将远程对象绑定到它似乎并不重要 - 在此示例中唯一似乎重要的是,无论何时创建UnicastRemoteObject,您都需要调用unexportObject以便完成后防止任何线程遗留.
在我的应用程序中,我已经确保我在我创建的每个UnicastRemoteObject上调用了unexportObject,但是RMI的"reaper"线程和"连接接受"线程仍然存在,当我的应用程序使用RMI资源完成时,阻止了我的JVM退出.
除了忘记取消导致UnicastRemoteObjects之外,还有什么东西可以导致RMI留下线程吗?
在Java中,Serialization使得对象的读取和写入非常容易.例如,以下代码片段主要是将对象写入流所需的全部内容:
ObjectOutputStream oos = ... //Initialize your output stream
Object toWrite = ... //Initialize what you want to write here
oos.writeObject(toWrite); //Writes the object to the stream
oos.flush();
Run Code Online (Sandbox Code Playgroud)
只要toWrite该类实现了Serializable接口,并且所有toWrite非transient成员变量也是如此,这将正常工作Serializable.换句话说,您尝试通过toWrite引用发送的整个对象层次结构必须是Serializable.假设这段代码的唯一问题是内部的东西toWrite不是Serializable.
如果层次结构不完整Serializable,则oos.writeObject(toWrite)抛出a 的调用java.io.NotSerializableException.这一切都很好,除了Exception不能为您提供快速解决问题所需的一切.它会告诉你哪个类无法序列化.您的堆栈跟踪可能如下所示:
java.io.NotSerializableException: some.package.and.ClassIDidntExplicitlyReference
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
...
at my.package.MyClass.codeThatWroteTheOffendingObject(MyClass.java:###)
Run Code Online (Sandbox Code Playgroud)
这种方式指向正确的方向,但在涉及深度对象层次结构的情况下,toWrite并不总是清楚违规类引用的来源.假设我分配toWrite给一个实例,MyClass并且我的实例MyClass有一个成员对象引用nonSerializableReference,该引用被设置为一个实例ClassIDidntExplicitlyReference,而不是Serializable.我希望看到以下内容打印出来:
my.package.MyClass.nonSerializableReference instanceof …Run Code Online (Sandbox Code Playgroud) 我偶然发现了有关一个奇怪的性能问题StringBuilder的append方法.我注意到似乎是一个愚蠢的错误 - 使用StringBuilder构造函数时的字符串连接(这甚至在NetBeans IDE中显示为警告).
版本1
int hash = -1; //lazily computed, also present in Version 2
int blockID = ... //0 to 1000, also present in Version 2
int threadID = ... //0 to 1000, also present in Version 2
boolean hashed = false; //also present in Version 2
@Override
public int hashCode(){
if(!hashed){
StringBuilder s = new StringBuilder(blockID+":"+threadID);
hash = s.toString().hashCode();
hashed= true;
}
return hash;
}
Run Code Online (Sandbox Code Playgroud)
在运行时期间创建了数百万个这样的对象,所以我想通过进行以下更改,它会提供一些加速:
版本2
@Override
public int hashCode(){ …Run Code Online (Sandbox Code Playgroud) 我在部署到Windows,Linux和Mac客户端的Java项目上使用git。对于此Java项目,我还维护用于在Mac / Linux上运行已编译二进制文件的* .sh脚本和用于在Windows上运行已编译二进制文件的.exe / .bat文件。我的开发环境是Windows。
Git的autocrlf功能将我的* .sh脚本中的行终止符转换为Windows格式,这使它们在部署后在Linux / Mac上无用。我想将它们保存为Unix格式,并让git单独保留行终止符。可以将git配置为忽略这些特定文件的autocrlf(单个文件夹中有三个文件)吗?如果是这样,怎么办?
长话短说,我有一个RMI服务器和客户端.服务器和客户端能够相互进行RMI调用.客户端连接到服务器后,服务器可以在客户端上快速连续进行数百个方法调用.
问题是这样 - 在大量服务器到客户端方法调用结束时,有些会失败,因为RMI声称它无法建立从服务器到客户端的连接,即使它之前的数百个调用都会成功.我不能发布任何真正的代码,因为这个项目相当大(约50k行),但这里是抛出异常的完整堆栈跟踪:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketException: Connection reset
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.findClassDefinition(Unknown Source)
at com.fabric.network.NetworkClassLoader.findClass(NetworkClassLoader.java:111)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.fabric.network.NetworkClassLoader.loadClass(NetworkClassLoader.java:131) …Run Code Online (Sandbox Code Playgroud) Java支持多维数组,表示为"数组数组".例如,我可以使用以下代码创建一个String数组数组:
int rows = ...
int cols = ...
String[][] array2d = new String[rows][cols];
Run Code Online (Sandbox Code Playgroud)
我想做的是让第二个维度"消失".换句话说,类似for循环for(String[] array : array2d) System.err.println(array);会打印出来:
null
...
null
Run Code Online (Sandbox Code Playgroud)
我之所以这样做是因为我已经分配了一堆String[]我想要插入的实例array2d.我有几个解决方案,但由于以下原因,两者似乎都不是最佳的:
解决方案1
我可以做类似的事情String[][] array2d = new String[rows][0],使用for循环来取消第一个维度,然后再填充行,但这对我来说似乎很难看,因为Java会String[]为每一行创建一个新的空,我真的不需要它至.
解决方案2
我也可以做类似的事情String[][] array2d = new String[][]{null, null, ... null},但这更糟糕,因为我必须array2d通过括号中的代码部分硬编码第一维的长度,这是令人作呕的.
我认识到这不是一个大问题,特别是当维度很小时,任何值得他的盐的程序员都会选择一些其他构造来创建多维度的数组.如果有一种方法可以在构造中部分分配多维数组的尺寸,我几乎只是好奇.