2024年3月

gRPC入门学习之旅(一)

  • 实现定义的服务

9.在“解决方案资源管理器”中,使用鼠标左键选中“Services”文件夹,然后在菜单栏上,依次选择“添加-->新建项”。

10.在“添加新项”对话框中,选择“ASP.NET Core-->代码”节点,然后选择“类”项。

11.在“名称”文本框中,输入 UserService.cs,然后选择“添加”按钮。如下图。

12.在文本编辑器打开的
UserService.cs
类文件,编写如下代码:

usingDemo.GrpcService.Protos;usingGrpc.Core;namespaceDemo.GrpcService.Services
{
public classUserInfoService : UserInfo.UserInfoBase

{
private readonly ILogger<GreeterService>_logger;public UserInfoService(ILogger<GreeterService>logger)
{

_logger
=logger;

}
/// <summary>
///实现了userinfo.proto协议文件中定义的GetUserInfo方法/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>

/// <returns></returns>
public override Task<UserInfoResult>GetUserInfo(UserInfoRequest request, ServerCallContext context)
{
//return base.GetUserInfo(request, context);//返回了user.proto协议文件中GetUserInfo方法定义的响应对象:UserInfoResult

return Task.FromResult(newUserInfoResult
{

UserName
=request.UserName,

Password
=request.Password,

Name
= $"姓名:张三",

Tel
="18800022269",

Sex
=1,

IsLogin
=false,
Age
= 10,
City
= "成都"});
}
/// <summary>
///实现了userinfo.proto协议文件中定义的Login方法/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>

public override Task<UserInfoResult>Login(UserInfoRequest request, ServerCallContext context)
{
//return base.Login(request, context);

if (request.UserName=="Admin" && request.Password=="666666666666")
{
//返回了user.proto协议文件定义的响应对象:UserInfoResult
return Task.FromResult(newUserInfoResult
{
UserName
=request.UserName,

Name
= $"姓名:张三",

Tel
= "18800022269",

Sex
= 1,
IsLogin
= true,
Age
= 10,
City
= "成都"});
}
return Task.FromResult(newUserInfoResult
{

IsLogin
= false});
}
/// <summary>
///实现了userinfo.proto协议文件中定义的Save方法/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>

public override Task<UserInfoResult>Save(UserInfoModifyRequest request, ServerCallContext context)
{
//return base.Save(request,context);//返回了user.proto协议文件定义的响应对象:UserInfoResult

return Task.FromResult(newUserInfoResult
{

UserName
=request.UserName,
Name
=request.Name,
Password
=request.Password,
Sex
=(int)request.Sex,
Age
=(int)request.Age,
City
=request.City,
Tel
=request.Tel,

});
}
}

}

继承的
UserInfo.UserInfoBase
是UserInfo.proto协议文件生成的类文件中的。

  • 注册
    UserInfoService
    服务

13.在Visual Studio 2022中进行重新生成,编译成功之后。我们需要将新建的UserInfoService服务在启动文件中进行注册。 在“解决方案资源管理器”中,找到Program.cs文件,使用鼠标双击打开
Program.cs
文件,在文本编辑器中,添加一行代码。将
业务服务
进行注册。如下面代码中斜体的一行代码,

usingDemo.GrpcService.Services;var builder =WebApplication.CreateBuilder(args);//Additional configuration is required to successfully run gRPC on macOS.//For instructions on how to configure Kestrel and gRPC clients on macOS, visithttps://go.microsoft.com/fwlink/?linkid=2099682 

//Add services to the container.
builder.Services.AddGrpc();var app =builder.Build();//Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();

app.MapGrpcService
<UserInfoService>();

app.MapGet(
"/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");


app.Run();

启动服务

到此,gRPC服务端就新建配置完成了,此时我们就可以启动该项目让其运行起来。

13.在Visual Studio 2022的菜单栏上,依次选择“调试”、“开始执行(不调试)”以运行服务。 Visual Studio 会弹出一个“信任Asp.Net Core SSL证书”的提示信息。如下图。

14.此处建议是点击“是”。然后会打开一个控制台窗口,并显示该服务的监听端口。如下图。

15.在上图中我们发现有2个地址
http://localhost:5209

https://localhost:7149
,如图中的两处框。这2个地址是我们在创建项目的时候,Visual Studio 2022在launchSettings.json配置文件中自动给我们配置的。gRPC客户端会使用到这2个地址,目的是给客户端请求请求地址,服务端将监听这两个端口。


《FFmpeg开发实战:从零基础到短视频上线》一书的“12.1.2  交叉编译Android需要的so库”介绍了如何在Windows环境交叉编译Android所需FFmpeg的so库,前文又介绍了如何在Linux环境交叉编译Android所需FFmpeg的so库,接下来介绍如何在Linux环境交叉编译Android所需x265的so库。

1、安装cmake

执行以下命令安装cmake

yum install cmake git

2、下载Linux版本的android-ndk-r21e(如已下载则忽略)

登录Linux服务器(比如华为云的欧拉系统),依次执行下面的命令。

cd /usr/local/src
curl -O https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip
unzip android-ndk-r21e-linux-x86_64.zip

3、上传x265的源码

从下面链接下载x265的源码包
https://bitbucket.org/multicoreware/x265_git/downloads/x265_3.5.tar.gz
解压x265源码包,修改x265_3.5/build/aarch64-linux目录下的crosscompile.cmake,把下面两行

set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)

改为下面两行

set(CMAKE_C_COMPILER aarch64-linux-android24-clang)
set(CMAKE_CXX_COMPILER aarch64-linux-android24-clang++)

4、配置x265的源码

进入x265_3.5下的build/aarch64-linux目录,执行以下命令配置x265:

export PATH=$PATH:/usr/local/src/android-ndk-r21e/toolchains/llvm/prebuilt/linux-x86_64/bin
./make-Makefiles.bash

命令行弹出的选项界面中,注意下列三项修改:
(1)把CMAKE_INSTALL_PREFIX这项改为/usr/local/app_x265(按向下键定位到该项,再按回车键,即可按照vi方式编辑路径)
(2)把ENABLE_ASSEMBLY这项改为OFF(按向下键定位到该项,再按回车键,即可把ON改为OFF)
(3)把ENABLE_CLI这项改为OFF(按向下键定位到该项,再按回车键,即可把ON改为OFF)
接着按c键开始配置,再按e键退出配置,然后按g键开始生成。

5、修改x265的编译规则

进入x265_3.5源码下的build/aarch64-linux/CMakeFiles/x265-shared.dir目录,注意修改下面三个文件:
(1)修改该目录的link.txt,把文件中的所有“libx265.so.199”替换为“libx265.so”。同时删除文件末尾的“ -lpthread -lrt”。
(2)同目录的relink.txt修改说明同link.txt。
(3)修改同目录下面的build.make,把该文件中的所有“libx265.so.199”替换为“libx265.so”,把所有的“libx265.so”替换为“libx265.so.199”。注意A和B互换名称的时候,可以设定第三个名称C,比如先把A替换为C,接着B替换为A,然后C替换为B。

6、编译和安装x265

进入x265_3.5源码下的build/aarch64-linux目录,执行以下命令编译和安装x265:

make
make install

7、调整x265的pc描述文件

修改/usr/local/app_x265/lib/pkgconfig下面的x265.pc,该文件的“Libs.private”选项里面去掉“-lrt”,也就是改成下面这行:

Libs.private: -lc++ -lm -lgcc -ldl -lgcc -ldl -ldl

8、添加PKG_CONFIG_PATH路径

Linux的profile文件位于用户初始目录的.bash_profile。执行以下命令编辑当前用户的profile文件:

cd
vi .bash_profile

往.bash_profile的文件末尾添加下面一行:

export PKG_CONFIG_PATH=/usr/local/app_x265/lib/pkgconfig:$PKG_CONFIG_PATH

保存并退出.bash_profile之后,执行以下命令加载环境变量:

source .bash_profile

然后执行下面的环境变量查看命令,确保x265的环境变量已经成功加载。

env | grep PKG

9、重新编译FFmpeg启用x265

打开《FFmpeg开发实战:从零基础到短视频上线》随书源码的chapter12/config_ffmpeg_full.sh,将该文件另存为config_ffmpeg_x265.sh,并在文件内部这行

  --enable-libx264 \

的下面增加如下一行配置

  --enable-libx265 \

接着把config_ffmpeg_x265.sh上传到服务器的FFmpeg源码目录,执行下面命令赋予可执行权限。

chmod +x config_ffmpeg_x265.sh

然后运行下列命令配置、编译和安装FFmpeg

./config_ffmpeg_x265.sh
make clean
make -j4
make install

10、把so文件导入App工程

(1)把FFmpeg交叉编译好的include目录(位于/usr/local/app_ffmpeg/include)整个复制到App工程的src/main/cpp目录下。
(2)在src\main目录下创建jniLibs目录,并在jniLibs下面创建子目录arm64-v8a,把FFmpeg交叉编译好的8个so文件(位于/usr/local/app_ffmpeg/lib)全部复制到arm64-v8a目录下。
(3)config_ffmpeg_x265.sh里面启用的几个第三方库的so文件也一块复制到arm64-v8a目录下,包括x264、x265、mp3lame、freetype等。
(4)给App工程的build.gradle的android→defaultConfig→externalNativeBuild→cmake节点内部增加下面配置。

    abiFilters "arm64-v8a"
    arguments '-DANDROID_STL=c++_shared' // FFmpeg集成x265时需要

如果不加,App运行时会报错“java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found”。
(5)在Android Studio上编译运行App工程,观察App是否正常运行。​

前言

最近在做采集软件的开发,由于我自己使用过Huaray和Basler两个品牌的相机,所以在设计软件时尝试设计统一的接口去控制不同品牌和型号相机的相同或类似的行为。当然,我的设计思路都是建立在调用各品牌SDK的基础上。
后来我去外网搜索,发现了一个开源项目Aravis,它通过提供一个通用的API,让我们能够不受相机的品牌或型号限制,自由地进行图像采集和相机控制,支持从简单的图像捕获到复杂的相机设置调整的一系列操作。

项目地址:
https://github.com/AravisProject/aravis

Aravis简介

Aravis是一个基于glib/gobject的库,允许开发者对遵循GenICam标准的网络相机进行通信和控制。它目前实现了工业相机使用的GigE和USB3协议。它还提供了一个简单的以太网相机模拟器和视频查看器。

依赖关系说明

  • Aravis库依赖于zlib、libxml2和glib2,若选择使用USB支持则需要依赖libusb1。
  • GStreamer插件除了需要Aravis库的依赖外,还依赖于GStreamer1。
  • 视频查看器依赖于GStreamer1、Gtk+3以及Aravis库的依赖。
  • 所需的版本在Aravis源码中的meson.build文件里有指定。
  • 可以只构建库本身,以此将依赖减少到最少。

安装过程

meson安装

由于Aravis是使用meson进行项目构建的,所以我们先安装meson:

apt install meson

安装完毕后验证是否安装成功

meson --version

aravis源文件下载

作者对aravis使用者的建议是最好使用发行版本而不是直接git checkout

在github上找到所需的aravis的发行版本,并下载:
https://github.com/AravisProject/aravis/releases
我选择的是0.8.31版本:

下载压缩包后解压即可

tar -xvf aravis-0.8.31.tar.xz

构建和安装aravis

进入工作目录,然后执行以下命令:

meson setup build
cd build
ninja
ninja install

在执行
meson setup build
可能会有安装失败的项点,错误解决方法可以参考文末的《安装过程中遇到的问题》

至此安装已完成

视频查看器

找到Aravis双击打开,即可查看已连接的相机设备

安装过程中遇到的问题

meson版本过低

我安装的aravis版本是0.8.31,这个版本aravis的编译依赖0.57.0及以上版本的meson,而我通过apt包管理器下载的meson版本为0.53.2,不满足需求。因此要对meson进行升级操作:

①首先安装或升级pip

apt install python3-pip
或
pip3 install --upgrade pip

②然后移除旧版本meson避免版本冲突

apt remove meson

③使用pip安装最新版本的meson
推荐使用--user选项,这样可以将Meson安装在用户目录下,避免对系统全局Python环境造成潜在的干扰

pip3 install --upgrade --user meson

④更新环境变量

~/.bashrc
文件中添加

export PATH="$HOME/.local/bin:$PATH"

然后重启系统生效

⑤验证meson版本
安装或升级完成后,通过以下命令检查Meson的版本,以确保安装或升级成功

meson --version

我的安装结果:

CMake版本过低

在构建项目的时候,提示了以下错误信息:

说明我系统中的CMake版本过低,需要升级。

注意:apt包管理器中的CMake版本不是最新的,所以我们不使用
apt install
更新CMake

我们采用从源码编译的方法更新:
①移除旧cmake防止版本冲突

apt remove cmake

②下载源码
进入
CMake官网
下载所需版本的源码,我下载的是3.29.0发布版本

③解压下载的源码包

tar -zxvf cmake-3.29.0.tar.gz

④编译和安装CMake

cd ./cmake-*
./bootstrap
make
make install

⑤添加环境变量

~/.bashrc
中添加

export PATH=/path/to/cmake/bin:$PATH

/path/to/cmake
是解压出来的源码的路径

⑥验证CMake

cmake --version

缺少GStreamer组件

直接使用包管理器安装即可

apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

参考文章

1.
Installation and Debug

Lama
是一个完全自托管的图像处理工具,基于最前沿的
AIGC
模型,它可以从图片中删除任何不需要的物体、缺陷或对象,
却看不到一点修改痕迹
~

在以前
,我们想将图片中的文字、水印去除,可以使用
ps
,但
ps
的学习成本比较高,没有那么容易上手,在面对复杂的几何结构和高分辨率图像时,
ps
的处理效果也不是很理想

造成这种情况的主要原因是传统的图像修复系统在构造图像网络和损失函数的过程中缺乏有效的感知视野,为了解决这个问题,
Lama
提供了一种新的方法,称为大型掩模修复

LaM Ais
基于:

· 一种新的修复网络架构,使用快速傅立叶卷积,具有图像宽的感受视野

· 高强度的视野感知损耗

· 大型训练掩码(
masks
),释放前两个组件的潜力

Lama
的修复网络在一系列数据集上提高到了最先进的水平,即使在复杂的场景中也能获得出色的性能,
Lama
可以处理超高分辨率的图像,并且在竞争基线中以更低的参数和计算成本实现了这一点

最新中文版:

百度网盘:
https://pan.baidu.com/s/12RVZlWwJBVX32UNGugz6Gg?pwd=ycnx

使用方法

1
、上传图片

2
、按住鼠标左键涂抹需要去除的对象

Lama
提供了白天和黑夜两种界面风格,拖动
Brush
来改变涂抹光标的大小,操作失误可以撤销或者恢复,对比按钮用来查看图片处理前后的效果,下载按钮保存图片到本地

博主
GTX2070
的显卡平均
1
秒处理一张图片,电脑是
A
卡或者集成显卡可以使用
cpu
模式,这里我也测了下大概
5
秒左右

注意事项

①项目安装路径不要包含中文

②使用过程中若不慎关闭软件后台,请重新打开,并刷新网页

上期文章推荐:动态水印也能去除?
ProPainter
一键视频抠图整合包下载

到目前为止,Orleans7的核心概念基本已经学完,我准备使用Orleans7做一个项目实战,来总结自己的学习效果。

项目效果

通过Orleans7来完成一个贪吃蛇游戏,要求如下:

  • 可以多人在线玩
  • 贪吃蛇可以上/下/左/右改方向
  • 贪吃蛇吃完食物,身体长度+1

项目暂定架构

初步设想,此游戏包括
一个Orleans7 Server端
,和
一个或多个
Winform游戏客户端。

Orleans7 Server需实现以下功能:

  • 实现GameGrain,和SnakeGrain。其中GameGrain中包含可多个Snake。
  • SnakeGrain每隔0.5s让所有Snake朝其当前方向走1步。

Winform游戏客户端需实现以下功能:

  • 需要使用IClusterClient创建SnakeGrain
  • 让SnakeGrain加入GameGrain。
  • 通过轮询/websocket,获取snake数据
  • 将通过websocket获取到的数据,通过Graphics将游戏界面/Snake/食物画出。
  • 可通过IClusterClient实现上下左右修改方向。

架构图

之后会按照以下架构图,实现此小游戏。