OpenCVSharp DNN - 使用Caffe框架模型

该博客展示了如何利用OpenCVSharp 4.5库在C#中执行OpenCV官方的Caffe模型,如bvlc_googlenet。代码详细解释了加载模型、预处理输入图像以及进行深度学习图像分类的过程。

用OpenCVSharp (4.5)跑一遍 OpenCV 官方教程。

原 OpenCV 官方教程链接:OpenCV: Load Caffe framework models

using System;
using OpenCvSharp;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp.Dnn;
using System.IO;

namespace ConsoleApp1
{
    class tutorial57 : ITutorial
    {
        public void Run()
        {

            int rszWidth = 224;
            int rszHeight = 244;
            float scale = 1;
            Scalar mean = new Scalar(104, 117, 123);
            Scalar std = new Scalar(0.0, 0.0, 0.0);
            bool swapRB = true;
            bool crop = false;
            int inpWidth = 224;
            int inpHeight = 161;
            string model = @"I:\csharp\images\caffe\bvlc_googlenet.caffemodel";
            string config = @"I:\csharp\images\caffe\bvlc_googlenet.prototxt";
         
<think> 我们遇到了一个XML布局错误:Duplicate attribute layout_height。这意味着在同一个View中,我们重复定义了`layout_height`属性。在XML文件中,每个属性在一个标签内只能出现一次。 解决方案: 1. 检查出问题的View标签,确保`android:layout_height`属性只出现一次。 2. 如果我们想要设置多个条件(例如权重和最小高度),我们应该在一个属性中设置,或者使用其他布局属性。 例如,如果我们同时使用权重和固定高度,这是不允许的。因为权重要求高度为0dp(或wrap_content,但权重分配规则不同),而固定高度会直接指定一个数值。 错误示例: ```xml <EditText android:layout_height="0dp" android:layout_height="match_parent" ... /> ``` 或者: ```xml <EditText android:layout_height="0dp" android:layout_height="200dp" ... /> ``` 正确做法:只保留一个`android:layout_height`属性。 另外,如果我们想要同时使用权重和最小高度,我们可以这样做: ```xml <EditText android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:minHeight="100dp" <!-- 设置最小高度 --> ... /> ``` 但是,如果我们看到错误信息是“Duplicate attribute”,那么就是字面意思:重复的属性。所以我们需要检查XML文件中是否有重复的属性定义。 下面是一个正确的示例,其中没有重复属性: ```xml <EditText android:id="@+id/et_input" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="9" android:gravity="start" android:hint="输入内容" android:inputType="textMultiLine" /> ``` 如果问题仍然存在,请检查XML文件中是否不小心复制粘贴了同一属性两次。 如果是在代码中动态设置布局参数,也要注意不要多次设置同一个属性。 在Android Studio中,我们可以通过以下步骤检查: 1. 打开有问题的XML文件。 2. 检查报错的View标签,查看是否有重复的属性。 3. 删除重复的属性,只保留一个。 例如,如果我们不小心写了两次`android:layout_height`,删除其中一个即可。 另外,注意:有时可能是拼写错误导致,例如将`layout_height`写成了`layou_height`,然后后面又写了一个正确的,这样就会有两个不同的属性(其中一个无效),但不会报重复属性错误。所以重复属性错误一定是相同的属性名出现了两次。 如果我们没有在同一个标签中看到重复属性,那么可能是由于合并布局时造成的,例如使用`<include>`标签时,被包含的布局中的属性与包含布局中指定的属性重复。这种情况下,我们需要确保在`<include>`标签中覆盖的属性不要在被包含布局中重复指定(或者使用`<merge>`标签来避免重复)。 但根据错误提示“Duplicate attribute layout_height”,我们首先应该检查当前XML文件中是否有重复定义。 下面给出一个常见错误的修正示例: 错误代码: ```xml <EditText android:layout_height="0dp" android:layout_height="match_parent" android:layout_width="match_parent" /> ``` 修正后: ```xml <EditText android:layout_height="match_parent" android:layout_width="match_parent" /> ``` 或者: ```xml <EditText android:layout_height="0dp" android:layout_width="match_parent" android:layout_weight="1" /> ``` 根据需求选择保留哪个高度值。 如果我们想要同时使用权重和固定高度,实际上是不行的,因为权重需要在LinearLayout中并且高度设置为0dp(或者wrap_content,但行为不同)。如果我们想要一个固定的最小高度,可以使用`minHeight`属性,但这不会影响权重分配。权重分配的是剩余空间。 因此,在遇到重复属性错误时,我们只需要删除重复的属性即可。 如果问题复杂,例如在代码中动态添加布局参数,那么我们需要检查代码中是否多次调用了设置布局参数的方法。例如: 错误代码: ```java ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0); et_input.setLayoutParams(params); // ... later ViewGroup.LayoutParams params2 = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); et_input.setLayoutParams(params2); // 重复设置,但不会报编译错误,而是运行时行为(最后一次生效) ``` 这种情况下,虽然不会报XML错误,但可能导致不符合预期的行为。我们需要确保布局参数只设置一次,或者根据条件合并设置。 总之,解决“Duplicate attribute layout_height”错误的关键是删除多余的属性定义。 如果问题发生在XML文件中,我们直接删除重复的属性即可。 如果问题发生在代码中,我们检查并确保只设置一次布局参数。 最后,注意:在Android Studio中,XML文件中的重复属性通常会以红色波浪线标出,并提示错误。我们可以根据IDE的提示快速定位并修复。 </think> 针对 XML 布局中出现 "Duplicate attribute layout_height" 错误的问题,我将详细解释原因并提供解决方案。这个错误通常发生在同一个视图元素中重复定义了 `android:layout_height` 属性。 ### 错误原因分析 ```xml <EditText android:id="@+id/et_input" android:layout_width="match_parent" android:layout_height="0dp" <!-- 第一次定义高度 --> android:layout_height="200dp" <!-- 第二次定义高度 (错误!) --> android:layout_weight="9" android:gravity="start" android:hint="输入内容" android:inputType="textMultiLine" /> ``` 错误原因: 1. **重复属性定义**:在同一个 XML 元素中多次声明了 `android:layout_height` 属性 2. **XML 语法规则**:XML 语法不允许同一个属性在同一元素中出现多次 3. **编译器限制**:Android XML 编译器无法处理重复属性,会直接报错 ### 解决方案 #### 1. 删除重复属性(最简单直接的解决方案) ```xml <EditText android:id="@+id/et_input" android:layout_width="match_parent" android:layout_height="0dp" <!-- 保留一个高度定义 --> android:layout_weight="9" android:gravity="start" android:hint="输入内容" android:inputType="textMultiLine" /> ``` #### 2. 使用样式代替重复属性(推荐用于复用场景) 在 `res/values/styles.xml` 中定义样式: ```xml <style name="WeightedInput"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">0dp</item> <item name="android:layout_weight">9</item> </style> ``` 应用到视图: ```xml <EditText android:id="@+id/et_input" style="@style/WeightedInput" android:gravity="start" android:hint="输入内容" android:inputType="textMultiLine" /> ``` #### 3. 使用包含布局(适合复杂视图结构) 创建 `res/layout/input_field.xml`: ```xml <EditText xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/et_input" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="9" android:gravity="start" android:hint="输入内容" android:inputType="textMultiLine" /> ``` 在主布局中包含: ```xml <include layout="@layout/input_field"/> ``` ### 错误排查技巧 1. **IDE 检查**: - Android Studio 会用红色下划线标记重复属性 - 错误信息:"Attribute 'layout_height' bound more than once" 2. **代码审查**: - 检查复制粘贴的代码片段 - 特别关注合并代码冲突时的重复属性 3. **XML 格式化工具**: 使用 Android Studio 的 `Reformat Code` (Ctrl+Alt+L) 自动格式化可以发现不规范写法 4. **Lint 检查**: 运行 `Analyze > Inspect Code` 进行静态分析,会报告"Duplicate attribute"错误 ### 高级技巧:条件布局属性 如果你需要根据屏幕尺寸使用不同的高度,正确做法是使用尺寸资源限定符而不是重复属性: 1. 在 `res/values/dimens.xml` 中: ```xml <dimen name="input_height">0dp</dimen> ``` 2. 在 `res/values-sw600dp/dimens.xml` (平板尺寸): ```xml <dimen name="input_height">300dp</dimen> ``` 3. 在布局中使用: ```xml <EditText android:layout_height="@dimen/input_height" ... /> ``` ### 最佳实践建议 1. **单一职责原则**:每个属性只定义一次 2. **使用样式**:复用通用属性组合 3. **布局分离**:复杂布局拆分成多个文件 4. **资源限定符**:根据不同配置使用不同资源 5. **代码审查**:特别注意XML合并时的冲突
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值