- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试实现 this项目,即 GenData.cpp,(用 C++ 编写)在 Java 中用于 KNN 分类器。
我遇到了这些代码行并卡住了:
matClassificationInts.push_back(intChar);
cv::FileStorage fsClassifications("classifications.xml", cv::FileStorage::WRITE);
fsClassifications << "classifications" << matClassificationInts;
fsClassifications.release();
在 C++ 中我们可以将整数传递给 push_back(),但在 Java 中我收到错误:“int cannot be converted to Mat”。
所以,第一个问题是:如何将 int 传递给 someMat.push_back()?
第二个:如何在 Java 中实现 FileStorage 或将 Mat 写入 *.xml 格式(并从 *.xml 读取 Mat)?
到目前为止,我的代码:
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import org.opencv.core.Core;
import static org.opencv.core.CvType.CV_32FC1;
import org.opencv.core.Mat;
import org.opencv.core.MatOfInt4;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import static org.opencv.imgproc.Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C;
import static org.opencv.imgproc.Imgproc.CHAIN_APPROX_SIMPLE;
import static org.opencv.imgproc.Imgproc.RETR_EXTERNAL;
import static org.opencv.imgproc.Imgproc.THRESH_BINARY_INV;
public class genData {
private static final int
MIN_CONTOUR_AREA = 100,
RESIZED_IMAGE_WIDTH = 20,
RESIZED_IMAGE_HEIGHT = 30;
public static void main(String[] args) throws IOException {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Scanner keyboard = new Scanner(System.in);
boolean exit = false;
Mat imgTrainingNumbers;
Mat imgGrayscale = new Mat();
Mat imgBlurred = new Mat();
Mat imgThresh = new Mat();
Mat imgThreshCopy = new Mat();
ArrayList<MatOfPoint> ptContours = new ArrayList<MatOfPoint>();
MatOfInt4 v4iHierarchy;
Mat matClassificationInts = new Mat();
Mat matTrainingImagesAsFlattenedFloats = new Mat();
int[] intValidChars = { '0', '1', '2',
'A', 'B', 'C'}; //Here I did not make List<Integer>, because I can't pass char to Integer.
Arrays.sort(intValidChars); //for binary search
imgTrainingNumbers = Imgcodecs.imread("test.png"); //here Text on white paper.
if (imgTrainingNumbers.empty()) {
System.out.println("err");
return;
}
Imgproc.cvtColor(imgTrainingNumbers, imgGrayscale, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(imgGrayscale, imgBlurred, new Size(5, 5), 0);
Imgproc.adaptiveThreshold(imgBlurred, imgThresh, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 11, 2);
/*
//imshow class implementation (found via google, works properly, but this block is commented for now)
Imshow im = new Imshow("imgThresh");
im.showImage(imgThresh);
imgThreshCopy = imgThresh.clone();
*/
Imgproc.findContours(imgThreshCopy, ptContours, new Mat(), RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
for (int i = 0; i < ptContours.size(); i++) {
if (Imgproc.contourArea(ptContours.get(i)) > MIN_CONTOUR_AREA) {
Rect boundingRect = Imgproc.boundingRect(ptContours.get(i));
Imgproc.rectangle(imgTrainingNumbers, boundingRect.tl(), boundingRect.br(), new Scalar(0, 0, 255), 2);
Mat matROI = imgThresh.submat(boundingRect.y, boundingRect.y + boundingRect.height, boundingRect.x, boundingRect.x + boundingRect.width);
Mat matROIResized = new Mat();
Imgproc.resize(matROI, matROIResized, new Size(RESIZED_IMAGE_WIDTH, RESIZED_IMAGE_HEIGHT));
/*
im.showImage(matROI);
im.showImage(matROIResized);
im.showImage(imgTrainingNumbers);
*/
String input = keyboard.nextLine();
int intChar = (int)input.charAt(0);
if (Arrays.binarySearch(intValidChars, intChar) >=0) {
/*
matClassificationInts.push_back(intChar);
//Here I'm getting an error.
*/
Mat matImageFloat = new Mat();
matROIResized.convertTo(matImageFloat, CV_32FC1);
Mat matImageFlattenedFloat = matImageFloat.reshape(1, 1);
matTrainingImagesAsFlattenedFloats.push_back(matImageFlattenedFloat);
}
}
}
//Here should go FileStorage stuff.
}
}
提前致谢。
附言使用 OpenCV_310 + Java(不是 JavaCV)
最佳答案
嗯,我已经自己解决了。 很脏,我想,但事实就是如此。如果您知道如何改进我的代码,我很乐意阅读您的评论。
1)我的第一个问题是关于将一个 int 放入 Mat(用于进一步制作 *.xml)。我避免了这种方法,并决定将 int(实际上是 Integer)放入 List 中。
Scanner keyboard = new Scanner(System.in);
String input = keyboard.nextLine();
int intChar = (int)input.charAt(0);
List<Integer> matClassificationInts = new ArrayList<Integer>();
if (Arrays.binarySearch(intValidChars, intChar) >=0) {
matClassificationInts.add(new Integer(intChar));
......
}
String dataImages = "";
for (Integer i : matClassificationInts) {
dataImages += i + " ";
}
我可以创建字符串(例如“49 48”字符 <->“1 0”整数)以将其保存在 *.xml 中(参见下一段)。
2) 第二个问题是关于从 Mat 中提取数据并将其存储在 *.xml 中。好吧,通过 C++,我可以通过 FileStorage 实现它:
cv::FileStorage fsClassifications("classifications.xml", cv::FileStorage::WRITE);
fsClassifications << "classifications" << matClassificationInts;
fsClassifications.release();
但 Java OpenCV 没有这样的功能,所以我循环遍历二维数组(Mat.rows() 和 Mat.cols())并通过 get() 方法提取所需的数据(Mat.get(row, col) -给出 double 组,数组长度 = 1):
String dataClassifications = "";
for (int i = 0; i < matTrainingImagesAsFlattenedFloats.rows(); i++) {
for (int j = 0; j < matTrainingImagesAsFlattenedFloats.cols(); j++) {
double[] temp = matTrainingImagesAsFlattenedFloats.get(i, j);
dataClassifications += temp[0] + " ";
}
dataClassifications += "\n";
}
现在,关于将数据保存到 *.xml:
我刚刚使用了 javafx.xml 和 org.wc3.dom 库。
制作了两个用于返回 DOM 节点的函数:
private static Node getMatXML(Document doc, String option_id, String type_id, String rows, String cols, String dt, String data) {
Element elem = doc.createElement(option_id);
elem.setAttribute("type_id", type_id);
elem.appendChild(getMatXMLElement(doc,"rows", rows));
elem.appendChild(getMatXMLElement(doc, "cols", cols));
elem.appendChild(getMatXMLElement(doc, "dt", dt));
elem.appendChild(getMatXMLElement(doc, "data", data));
return elem;
}
private static Node getMatXMLElement(Document doc, String name, String value) {
Element node = doc.createElement(name);
node.appendChild(doc.createTextNode(value));
return node;
}
并使用这些函数来创建 *.xml:
分类.xml:
DocumentBuilderFactory icFactory_images = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder_images;
try {
icBuilder_images = icFactory_images.newDocumentBuilder();
Document doc = icBuilder_images.newDocument();
Element mainRootElement = doc.createElement("opencv_storage");
doc.appendChild(mainRootElement);
mainRootElement.appendChild(getMatXML(doc, "classifications", "opencv-matrix", rowsImages, colsImages, "i", dataImages));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
String filename = "classifications.xml";
File file = new File(filename);
StreamResult console = new StreamResult(file); //(System.out)
transformer.transform(source, console);
} catch (Exception e) {
e.printStackTrace();
}
图片.xml:
DocumentBuilderFactory icFactory_classifications = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder_classifications;
try {
icBuilder_classifications = icFactory_classifications.newDocumentBuilder();
Document doc = icBuilder_classifications.newDocument();
Element mainRootElement = doc.createElement("opencv_storage");
doc.appendChild(mainRootElement);
mainRootElement.appendChild(getMatXML(doc, "images", "opencv-matrix", rowsClassifications, colsClassifications, "f", dataClassifications));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
String filename = "images.xml";
File file = new File(filename);
StreamResult console = new StreamResult(file); //(System.out)
transformer.transform(source, console);
} catch (Exception e) {
e.printStackTrace();
}
因此,例如,生成的分类文件是:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<opencv_storage>
<classifications type_id="opencv-matrix">
<rows>2</rows>
<cols>1</cols>
<dt>i</dt>
<data>49 48 </data>
</classifications>
</opencv_storage>
我对这张照片做了测试:
通过 GenData.cpp(见有问题的链接 - 第一行)和我的 Java 代码(完整代码见下文)。两个程序都给了我相同的结果:
对于 Java OpenCV Imshow 实现,您可以查看 this link (不是我的)。
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import org.opencv.core.Core;
import static org.opencv.core.CvType.CV_32FC1;
import org.opencv.core.Mat;
import org.opencv.core.MatOfInt4;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import static org.opencv.imgproc.Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C;
import static org.opencv.imgproc.Imgproc.CHAIN_APPROX_SIMPLE;
import static org.opencv.imgproc.Imgproc.RETR_EXTERNAL;
import static org.opencv.imgproc.Imgproc.THRESH_BINARY_INV;
//XML - write.
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class genData {
private static final int
MIN_CONTOUR_AREA = 100,
RESIZED_IMAGE_WIDTH = 20,
RESIZED_IMAGE_HEIGHT = 30;
public static void main(String[] args) throws IOException {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Scanner keyboard = new Scanner(System.in);
Mat imgTrainingNumbers;
Mat imgGrayscale = new Mat();
Mat imgBlurred = new Mat();
Mat imgThresh = new Mat();
Mat imgThreshCopy = new Mat();
ArrayList<MatOfPoint> ptContours = new ArrayList<MatOfPoint>();
MatOfInt4 v4iHierarchy = new MatOfInt4();
List<Integer> matClassificationInts = new ArrayList<Integer>();
Mat matTrainingImagesAsFlattenedFloats = new Mat();
int[] intValidChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'E', 'H',
'K', 'M', 'O', 'P', 'T',
'X', 'Y'};
Arrays.sort(intValidChars);
imgTrainingNumbers = Imgcodecs.imread("01.png");
if (imgTrainingNumbers.empty()) {
System.out.println("Error: file is not found");
return;
}
Imgproc.cvtColor(imgTrainingNumbers, imgGrayscale, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(imgGrayscale, imgBlurred, new Size(5, 5), 0);
Imgproc.adaptiveThreshold(imgBlurred, imgThresh, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 11, 2);
Imshow im = new Imshow("imgThresh");
im.showImage(imgThresh);
imgThreshCopy = imgThresh.clone();
Imgproc.findContours(imgThreshCopy, ptContours, v4iHierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
for (int i = 0; i < ptContours.size(); i++) {
if (Imgproc.contourArea(ptContours.get(i)) > MIN_CONTOUR_AREA) {
Rect boundingRect = Imgproc.boundingRect(ptContours.get(i));
Imgproc.rectangle(imgTrainingNumbers, boundingRect.tl(), boundingRect.br(), new Scalar(0, 0, 255), 2);
Mat matROI = imgThresh.submat(boundingRect.y, boundingRect.y + boundingRect.height, boundingRect.x, boundingRect.x + boundingRect.width);
Mat matROIResized = new Mat();
Imgproc.resize(matROI, matROIResized, new Size(RESIZED_IMAGE_WIDTH, RESIZED_IMAGE_HEIGHT));
im.showImage(matROI);
im.showImage(matROIResized);
im.showImage(imgTrainingNumbers);
String input = keyboard.nextLine();
int intChar = (int)input.charAt(0);
if (Arrays.binarySearch(intValidChars, intChar) >=0) {
matClassificationInts.add(new Integer(intChar));
Mat matImageFloat = new Mat();
matROIResized.convertTo(matImageFloat, CV_32FC1);
Mat matImageFlattenedFloat = matImageFloat.reshape(1, 1);
matTrainingImagesAsFlattenedFloats.push_back(matImageFlattenedFloat);
}
}
}
String dataImages = "";
for (Integer i : matClassificationInts) {
dataImages += i + " ";
}
String dataClassifications = "";
for (int i = 0; i < matTrainingImagesAsFlattenedFloats.rows(); i++) {
for (int j = 0; j < matTrainingImagesAsFlattenedFloats.cols(); j++) {
double[] temp = matTrainingImagesAsFlattenedFloats.get(i, j);
dataClassifications += temp[0] + " ";
}
dataClassifications += "\n";
}
String rowsImages = String.valueOf(matClassificationInts.size());
String colsImages = "1";
String rowsClassifications = String.valueOf(matTrainingImagesAsFlattenedFloats.rows());
String colsClassifications = String.valueOf(matTrainingImagesAsFlattenedFloats.cols());
DocumentBuilderFactory icFactory_images = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder_images;
try {
icBuilder_images = icFactory_images.newDocumentBuilder();
Document doc = icBuilder_images.newDocument();
Element mainRootElement = doc.createElement("opencv_storage");
doc.appendChild(mainRootElement);
mainRootElement.appendChild(getMatXML(doc, "classifications", "opencv-matrix", rowsImages, colsImages, "i", dataImages));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
String filename = "classifications.xml";
File file = new File(filename);
StreamResult console = new StreamResult(file); //(System.out)
transformer.transform(source, console);
} catch (Exception e) {
e.printStackTrace();
}
DocumentBuilderFactory icFactory_classifications = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder_classifications;
try {
icBuilder_classifications = icFactory_classifications.newDocumentBuilder();
Document doc = icBuilder_classifications.newDocument();
Element mainRootElement = doc.createElement("opencv_storage");
doc.appendChild(mainRootElement);
mainRootElement.appendChild(getMatXML(doc, "images", "opencv-matrix", rowsClassifications, colsClassifications, "f", dataClassifications));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
String filename = "images.xml";
File file = new File(filename);
StreamResult console = new StreamResult(file); //(System.out)
transformer.transform(source, console);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Finished.");
System.exit(0);
}
private static Node getMatXML(Document doc, String option_id, String type_id, String rows, String cols, String dt, String data) {
Element elem = doc.createElement(option_id);
elem.setAttribute("type_id", type_id);
elem.appendChild(getMatXMLElement(doc,"rows", rows));
elem.appendChild(getMatXMLElement(doc, "cols", cols));
elem.appendChild(getMatXMLElement(doc, "dt", dt));
elem.appendChild(getMatXMLElement(doc, "data", data));
return elem;
}
private static Node getMatXMLElement(Document doc, String name, String value) {
Element node = doc.createElement(name);
node.appendChild(doc.createTextNode(value));
return node;
}
}
关于Java OpenCV FileStorage 和 Mat.push_back,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38243026/
我已经彻底搜索过,但没有找到直接的答案。 将 opencv 矩阵 (cv::Mat) 作为参数传递给函数,我们传递的是智能指针。我们对函数内部的输入矩阵所做的任何更改也会改变函数范围之外的矩阵。 我读
是否可以有一个垫子分隔线(一条水平线分隔两个垫子选项)? 我试过: Cars Volvo Saab Mercedes Audi
使用的浏览器 - Chrome 67.0.3396.99 我创建了一个 DialogsModule它有一个组件 ConfirmDialog.component.ts使用以下模板 confirm-dia
我正在尝试使用 mat-toolbar 但出现错误: mat-menu.component.html: Responsive Navigation Menu I
我正在创建 angular 7 网络应用程序,并使用一个 mat-select 下拉菜单和一个 mat-paginator。现在我隐藏 mat-select 向下箭头。 Here is the mat
在我的应用程序中,我有一个通过引用接收 cv::Mat 对象的函数。这是函数的声明: void getChains(cv::Mat &img,std::vector &chains,cv::
我使用了独立的 EMA (1.5.0) 和 eclipse 插件(在 eclipse 4.5 中)来分析我的堆转储。 我想查看任何无法访问的对象信息,我已尝试在我的首选项和命令行选项 -keep_un
我是 flex 的新手,我的垫子 table 做得很好。 不幸的是,我的标题没有遵循我的单元格宽度。 这是我的结果的图片。 如您所见,我的标题与我的单元格不对齐。 这是我的 CSS 代码,就像我说我是
我试图在我的 Material 表上使用 mat-sort 和 mat-paginator,但似乎不起作用。 Table 确实获取了 dataSource.data 中的数据,它也显示在 mat-ta
我试图在我的 Material 表上使用 mat-sort 和 mat-paginator,但似乎不起作用。 Table 确实获取了 dataSource.data 中的数据,它也显示在 mat-ta
我想在每个 mat-option 文本上设置悬停样式,我希望文本显示在 mat-option 之外。为了实现这一点,我应用了非常高的 z-index 值,但没有任何改变。我尝试将 z-index 添加
默认情况下 mat-drawer-container/mat-sidenav-container 和 mat-drawer/mat-sidenav 高度基于 mat-drawer-cont
在 mat-card-header 中提供图像头像通过 mat-card-avatar 得到很好的支持. 在许多用例中,我们希望使用图标而不是图像作为卡片的“头像”。 有没有一种简单的方法可以用图标替
我想要一个包含 2 列的网格列表,并且在这些列中我想要 2 个垂直堆叠的复选框。 我看过 this question 这确实有点 工作,但我想知道是否有更简洁的方法解决这个问题,因为我必须使用大量的
更新:stackbliz https://angular-2wqf4b.stackblitz.io 我正在构建一个比较屏幕,我们可以在其中比较两个项目。我试图将这两项显示为两个 mat-cards里
试图模仿 Material guide 的外观,我无法让工具栏的阴影呈现在 mat-sidenav-container 元素之上: 显示工具栏和 sidenav 的页面,但投影不可见: 单独显示工具栏
请注意,分页/排序无法正常工作。分页不显示它显示的元素数量并且排序不起作用,但是如果您删除 html 文件中的行 *ngIf="dataSource?.filteredData.length > 0"
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Proper stack and heap usage in C++? Heap vs Stack allo
单击每个单选按钮时,我需要为每个垫卡添加背景。背景应仅适用于与单击的垫单选按钮对应的垫卡。
Mat a = (Mat_(3,3) = 2 int dims; //! the number of rows and columns or (-1, -1) when the arr
我是一名优秀的程序员,十分优秀!