Integrating Dokuwiki with Mantis

本文详细介绍了如何将MantisBT与DokuWiki进行集成,包括自定义DokuWiki以匹配Mantis认证、调整授权基于Mantis访问级别、在问题视图页面添加Wiki链接、提供Mantis与Wiki页面之间的映射以及正确管理HTTP认证。

原文链接:http://www.mantisbt.org/wiki/doku.php/mantisbt:issue:7075:integration_with_dokuwikiIntegrating DokuWiki with Mantis

Disclaimer

This document describes the steps needed to integrate DokuWiki with Mantis. The method described here was originally tested with mantis version 1.1.0rc2 and dokuwiki rc2009-12-02, and should work with subsequent versions (modulo bugs). It may work with older versions of mantis provided you make the File Changes described below.

Integration Functionality

The integration between Mantis and DokuWiki so far achieves the following:

  • Customises DokuWiki to honour Mantis authentication (i.e. single sign-on).
  • Customises DokuWiki authorisation based on Mantis access levels (i.e. groups).
  • Adds a Wiki link on the issue view simple/advanced pages to their corresponding Wiki issue page.
  • Adds a Wiki menu option which maps to the corresponding project Wiki page, or general page in case of “All Projects”.
  • Provides a way for Wiki pages to link to Mantis issues, e.g. 7075.
  • Correctly manages HTTP Authentication. See ( http://www.mantisbt.org/bugs/view.php?id=12458).

Tips

Following are some tips that are of interest to Mantis / DokuWiki integration:

  • To define a template for all Wiki pages within a namespace, create _template.txt in the namespace folder (namespace is located into the DOKUWIKI_ROOT/data/mantis directory). All pages created within this namespace will use the contents of the templates as a start point. This will affect the way the Wiki is structured. For example, if all issues within a project have a namespace, then they can all share one template, if there is a namespace per category, then there can be a template per category. The exact structure to be used should be configurable through Mantis configuration. However, the actual structure currently implemented is described in a tip later on in this section.
  • The Wiki menu links in Mantis are equivalent to internal links for mantis:project: where:
    • mantis is the value of $g_wiki_root_namespace from config_inc.php (note that this is not configurable per-project, it is specifically looked up as a global)
    • project is the name of the current project, or nothing for ALL PROJECTS (ie. you get just mantis: which resolves to mantis:start if your start config setting is still the install default)
  • The View Issue Details Wiki links in Mantis are equivalent to internal links for mantis:project:issue:NNNN where:
    • mantis and project are as described above for that Mantis project
    • issue is just that word “issue” and is the namespace for all issues in this project
    • NNNN is the numeric ID of the Mantis issue without leading zeros, and is a page, not a namespace
  • How Wiki access levels are determined: The Mantis auth backend included below takes the namespace containing the object being accessed, extracts the 2nd component, and looks it up in a flat list of Mantis projects. If there is a match, that project’s access level is used, and if not, the global (ALL PROJECTS) access level is used. This means that mantis:project: and mantis:subproject: both get the access level of those Mantis projects, but mantis:project:subproject: gets the access level of project, AND playground:project: also gets the access level of project even though it has nothing to do with the $g_wiki_root_namespace used by the various Wiki links on the Mantis side. This allows you to implement any number of areas in your wiki that use Mantis projects for access control, with the restriction that all namespaces must be of the form top_level:mantis_project:* (ie. any namespace just under a top-level namespace which matches a Mantis project name will use that project access level for itself and its child namespaces).
  • Another consequence of the simplistic code here is that it fails to adjust when $g_wiki_root_namespace is an empty string. In that case, the mapping function on the Mantis side omits the mantis: component in the Wiki namespace string, thus popping the flat project list up to the top level. But then the auth backend code below fails to find it, and every project Wiki link from Mantis takes you to a place that has only global access levels and your project access settings appear to be ignored. Of course, if you create a namespace just under any top level namespace with a Mantis project’s name, that will continue to work fine.
  • Rename (if necessary) your projects and subprojects so that all their names are legal pagename identifiers. Otherwise the access level code will fail to map Wiki namespaces back into Mantis projects, and users will get global access levels instead of their project access level.
  • DokuWiki will see groups for each combination of Mantis project and access level that exist for the current user. For example:
my_namespace:my_project:* @ALL                 0
my_namespace:my_project:* @MYPROJECT_VIEWER    1
my_namespace:my_project:* @MYPROJECT_DEVELOPER 8

Mantis Configuration

Add the following configuration items to config_inc.php and customize them for your installation. Copy the corresponding block fromconfig_defaults_inc.php if your mantis version is recent enough to have it. Note however that the list of valid wiki engines may be out of date; as of 1.2.6 the correct list is in the switch statement incore/wiki_api.php.

	#####################
	# Wiki Integration
	#####################
 
	# Wiki Integration Enabled?
	$g_wiki_enable = OFF;
 
	# Wiki Engine
	$g_wiki_engine = 'dokuwiki';
 
	# Wiki namespace to be used as root for all pages relating to this mantis installation.
	$g_wiki_root_namespace = 'mantis';
 
	# URL under which the wiki engine is hosted.  Must be on the same server.
	$g_wiki_engine_url = $t_protocol . '://' . $t_host . '/%wiki_engine%/';

Tip: If you are using different subdomains (eg. mantis lives at: bugs.example.com and doku lives at wiki.example.com) then you need to make the cookies accessible to both subdomains. In your mantisconfig_inc.php, set

        $g_wiki_engine_url = 'http://wiki.example.com/';
        $g_cookie_domain = '.example.com';   // So wiki and bugs can share cookie info

Don’t forget to change g_wiki_enable to ON later once you are done setting up DokuWiki.

DokuWiki Steps

Installation

Install DokuWiki and make sure it is working properly. This involves making sure that you can create pages, edit them, view them, etc.

Core Configuration

Add/modify the configuration values show below in your DokuWiki installation. Recent versions (eg. 2011-05-25a “Rincewind”) can have these indokuwiki\conf\local.protected.php, but older versions will have to put them in a file that may be overwritten later. Usedokuwiki\conf\local.php if you do not use the Admin interface’s config plugin (it will delete manually added lines!). Otherwise usedokuwiki\conf\dokuwiki.php where the default settings are located, but beware this will get overwritten during updates, so you will need to manually merge changes.

In fact a fix is needed to implement the two settings to the config page. (fix in form of plugin is already done herehttp://www.mantisbt.org/wiki/doku.php/mantisbt:issue:8253 but contains other changes)

#
# Add the following lines:
#
 
define( 'MANTIS_ROOT', 'c:/inetpub/wwwroot/mantisbt/' );  // file path to Mantis, must terminate with /
define( 'MANTIS_URL', 'http://localhost/mantisbt/' );     // url to Mantis, must terminate with /
 
#
# Once you have inc\auth\mantis.class.php created, modify the following configuration options to match the values below.
# With modern versions of dokuwiki, the bundled config plugin can set these values, otherwise uncomment them here.
#
 
# $conf['useacl']       = 1;                // Use Access Control Lists to restrict access?
# $conf['authtype']     = 'mantis';         // which authentication backend should be used
# $conf['defaultgroup'] = 'VIEWER';         // Default groups new Users are added to
# $conf['superuser'] = '@ADMINISTRATOR';    // allows mantis administrator to access dokuwiki admin area
 
#
# If selecting the mantis auth backend results in fatal errors from redeclaration of utf8 functions, uncomment this:
#
# require_once( MANTIS_ROOT . 'core.php' );

(utf8 redeclaration error reference: http://www.mantisbt.org/bugs/view.php?id=11769)

Authorisation Configuration

Add the following to the end of acl.auth.php:

*	@VIEWER		1
*	@REPORTER	2
*	@UPDATER	4
*	@DEVELOPER	8
*	@MANAGER	16
*	@ADMINISTRATOR	16

This will get you started. See the Tips section above for information about per-project group mappings.

Mantis Authentication Backend (Single Sign-On)

Create dokuwiki\inc\auth\mantis.class.php with the code below.

<?php
/**
 * Mantis auth backend
 *
 * Uses external Trust mechanism to check against Mantis'
 * user cookie.
 * 13/12/2009 ~ @Tiago Gomes:
 * added modifications to make possible to set project related user rights.(http://www.mantisbt.org/bugs/view.php?id=8249)
 * added modifications so that mantis support logging in/out from DokuWiki’s login page (http://www.mantisbt.org/bugs/view.php?id=8277)
 * 
 *
 * @author    Victor Boctor (http://www.futureware.biz)
 * 
 */
require_once( MANTIS_ROOT . 'core.php' );
 
#dbg($GLOBALS);
 
class auth_mantis extends auth_basic {
    /**
     * Constructor.
     *
     * Sets additional capabilities and config strings
     */
    function auth_mantis(){
        $this->cando['external'] = true;
 
        $this->cando['logoff' ] = true; // module has a logoff method
    }
    
    /**
     * Authenticates the user using Mantis APIs.
     */
    function trustExternal($user,$pass,$sticky=false){
        global $USERINFO;
        global $conf;
 
        $ValidUser = false;
 
        // Manage HTTP authentication with Negotiate protocol enabled
        $user = auth_prepare_username($user);
	$pass = auth_prepare_password($pass);
        // This is necessary in all cases where Authorization HTTP header is always set
	if(auth_is_user_authenticated())
	{
	    $user='';
	}
 
        // Has a user name been provided?
        if ( !empty ( $user ) )
        {   
            // User name provided, so login via form in progress...
            // Are the specified user name and password valid?
            if ( auth_attempt_login ( $user, $pass, $sticky ) )
            {   
                // Credential accepted...
                $_SERVER['REMOTE_USER'] = $user; // Set the user name (makes things work...)
                $ValidUser = true; // Report success.
            }
            else
            {   
                // Invalid credentials              
                        if ( !$silent )
                {   
                    msg ( $lang [ 'badlogin' ], -1 );
                }
                
                $ValidUser = false;
            }
        }
        else
        {   
            // No user name provided.
            // Is a user already logged in?
            if ( auth_is_user_authenticated ( ) )
            {   
                // Yes, a user is logged in, so set the globals...
                // is it a media display or a page?
                if (isset($_REQUEST['media'])) {
                    //media
                    $t_project_name = explode( ':', getNS( getID("media",false) ) );
                } else {
                    // normal page
                    $t_project_name = explode( ':', getNS( getID() ) );
                }
                $t_project_id = project_get_id_by_name( $t_project_name[1] );
                $t_access_level = access_get_project_level( $t_project_id );
                $t_access_level_string = strtoupper( MantisEnum::getLabel( config_get( 'access_levels_enum_string' ),  $t_access_level ) ); // mantis 1.2.0rc
                // $t_access_level_string = strtoupper( get_enum_to_string( config_get( 'access_levels_enum_string' ),  $t_access_level ) ); 
                $t_access_level_string_ex = strtoupper( $t_project_name[1] ) . '_' . $t_access_level_string;
 
                $USERINFO['grps'] = array( $t_access_level_string, $t_access_level_string_ex );
                $USERINFO[ 'pass' ] = current_user_get_field ( 'password' );
                $USERINFO[ 'name' ] = current_user_get_field ( 'username' );
                $USERINFO[ 'mail' ] = current_user_get_field ( 'email' );
                
                $_SERVER[ 'REMOTE_USER' ] = $USERINFO[ 'name' ];
                $_SESSION[ $conf[ 'title' ]][ 'auth' ][ 'user' ] = $USERINFO[ 'name' ];
                $_SESSION[ $conf[ 'title' ]][ 'auth' ][ 'info' ] = $USERINFO;
                
                $ValidUser = true;
            }
            else
            {   
                $ValidUser = false;
            }
        }
        
        // Is there a valid user login?
        if ( true != $ValidUser )
        {   
            // No, so make sure any existing authentication is revoked.
            auth_logoff ( );
        }
        
        return $ValidUser;
    }
    /**
     * Logout from Mantis
     */
    function logOff(){
        auth_logout();
    }
 
    /**
     * Get user data
     * (needed for e-mail subscriptions)
     *
     * @author Martin Arends http://www.web-gestaltung.de
     */
    function getUserData($user) 
    {
      $data = array();
      
      $t_user_id = user_get_id_by_name( $user );
 
      if (isset($_REQUEST['media'])) {
          //media
          $t_project_name = explode( ':', getNS( getID("media",false) ) );
      } else {
          // normal page
          $t_project_name = explode( ':', getNS( getID() ) );
      }
 
      $t_project_id   = project_get_id_by_name( $t_project_name[1] );
      $t_access_level = access_get_project_level( $t_project_id, $t_user_id );
      $t_access_level_string    = strtoupper( MantisEnum::getLabel( config_get( 'access_levels_enum_string' ),  $t_access_level ) );
      $t_access_level_string_ex = strtoupper( $t_project_name[1] ) . '_' . $t_access_level_string;
      
      $data['name'] = $user;
      $data['grps'] = array( $t_access_level_string, $t_access_level_string_ex );
      $data['mail'] = user_get_email( $t_user_id );
      return $data;
    }
}
 

This codes already contains the following mods:

  • Issue 8249 which makes it possible to set project related user rights.
  • Support logging in/out from DokuWiki’s login page Issue 8277

If you want the original code, you can see the wiki history

Mantis Syntax Plug-in

This plugin is to be placed in dokuwiki\lib\plugins\mantis\syntax.php. Create themantis subdirectory underplugins if necessary.

<?php
/**
 * Mantis Plugin: Hyperlinks references to Mantis Issues
 * 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Victor Boctor (http://www.futureware.biz)
 */
 
 
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
 
/**
 * A plug-in that hyper links references to Mantis issues.  References
 * to Mantis issues should use the following format: ~~Mantis:123~~.
 *
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_mantis extends DokuWiki_Syntax_Plugin {
 
    /**
     * return some info
     */
    function getInfo(){
        return array(
            'author' => 'Victor Boctor',
            'email'  => 'vboctor at users . sourceforge . net',
            'date'   => '2006-05-18',
            'name'   => 'Mantis Issues Plugin',
            'desc'   => 'Support References to Mantis Issues',
            'url'    => 'http://www.futureware.biz',
        );
    }
 
    /**
     * What kind of syntax are we?
     */
    function getType(){
        return 'substition';  # typo is intentional
    }
   
    /**
     * What about paragraphs?
     */
    function getPType(){
        return 'normal';
    }
 
    /**
     * Where to sort in?
     */ 
    function getSort(){
        return 156;
    }
 
 
    /**
     * Connect pattern to lexer
     */
    function connectTo($mode) {
        $this->Lexer->addSpecialPattern('~~Mantis:[0-9]+~~', $mode, 'plugin_mantis');
    }
 
 
    /**
     * Handle the match
     */
    function handle($match, $state, $pos, &$handler){
        $match = substr( $match, 9, -2 ); // strip "~~Mantis:" from start and "~~" from end
        return array( strtolower( $match ) );
    }
 
    /**
     * Create output
     */
    function render($format, &$renderer, $data) {
        if ( $format == 'xhtml' ) {
			$renderer->externallink( MANTIS_URL . 'view.php?id=' . $data[0], $data[0] );
            return true;
        }
        return false;
    }
}
 

Mantis File Changes for versions before 1.1.0rc2

If you use mantis 1.1.0rc2 (or later), the following steps are already done and you just need to set

	$g_wiki_enable = ON;

in your config_inc.php.

If you use a mantis version which is older than 1.1.0rc2 please check if any of the changes below still need to be done.

wiki_api.php

Create mantis/core/wiki_api.php with the following content:

<?php
	# Mantis - a php based bugtracking system
	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
	# Copyright (C) 2002 - 2006  Mantis Team   - mantisbt-dev@lists.sourceforge.net
	# This program is distributed under the terms and conditions of the GPL
	# See the README and LICENSE files for details
 
	# --------------------------------------------------------
	# $Id: $
	# --------------------------------------------------------
 
	require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'helper_api.php' );
	require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'utility_api.php' );
	require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'database_api.php' );
	require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'authentication_api.php' );
	require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'gpc_api.php' );
	require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'access_api.php' );
	require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'project_api.php' );
	require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'wiki_' . config_get( 'wiki_engine' ) . '_api.php' );
 
	# ----------------------
	# Calls a function with the specified name (not including prefix) and given the array
	# of parameters supplied.  An example prefix is "wiki_dokuwiki_".
	function wiki_call( $p_function, $p_args_array ) {
		$t_function = 'wiki_' . config_get_global( 'wiki_engine' ) . '_' . $p_function;
		return call_user_func_array( $t_function, $p_args_array );
	}
 
	# ----------------------
	# Checks if the Wiki feature is enabled or not.
	function wiki_is_enabled() {
		return config_get( 'wiki_enable' ) == ON;
	}
 
 	# ----------------------
	# Ensures that the wiki feature is enabled.
	function wiki_ensure_enabled() {
		if ( !wiki_is_enabled() ) {
			access_denied();
		}
	}
 
	# ----------------------
	# Gets the wiki URL for the issue with the specified id.
	function wiki_get_url_for_issue( $p_issue_id ) {
		return wiki_call( 'get_url_for_issue', array( $p_issue_id ) );
	}
 
	# ----------------------
	# Gets the wiki URL for the project with the specified id.  The project id can be ALL_PROJECTS.
	function wiki_get_url_for_project( $p_project_id ) {
		return wiki_call( 'get_url_for_project', array( $p_project_id ) );
	}
?>
 

wiki_dokuwiki_api.php

Create mantis/core/wiki_dokuwiki_api.php with the following content:

<?php
	# Mantis - a php based bugtracking system
	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
	# Copyright (C) 2002 - 2006  Mantis Team   - mantisbt-dev@lists.sourceforge.net
	# This program is distributed under the terms and conditions of the GPL
	# See the README and LICENSE files for details
 
	# --------------------------------------------------------
	# $Id: $
	# --------------------------------------------------------
 
	# ----------------------
	# Gets the URL for the page with the specified page id.  This function is used
	# internally by this API.
	function wiki_dokuwiki_get_url_for_page_id( $p_page_id ) {
		$t_root_url = config_get_global( 'wiki_engine_url' );
 
		$t_root_namespace = config_get( 'wiki_root_namespace' );
 
		if ( is_blank( $t_root_namespace ) ) {
			$t_page_id = $p_page_id;
		} else {
			$t_page_id = $t_root_namespace . ':' . $p_page_id;
		}
 
		return $t_root_url . 'doku.php?id=' . urlencode( $t_page_id );
	}
 
	# ----------------------
	# Gets the page id for the specified issue.  The page id can then be converted
	# to a URL using wiki_dokuwiki_get_url_for_page_id().
	function wiki_dokuwiki_get_page_id_for_issue( $p_issue_id ) {
		$c_issue_id = db_prepare_int( $p_issue_id );
 
		$t_project_id = bug_get_field( $p_issue_id, 'project_id' );
		$t_project_name = project_get_name( $t_project_id );
 
		# create a namespace for the project to contain all project documentation.
		# create within it a namespace for issues.  This is to allow the creation of a _template.txt
		# file to act as the template for issues belonging to this project.
		return $t_project_name . ':issue:' . $c_issue_id;
 
          # when using a different language you also could use the translation of 'issue' instead
          # but when working in a multilingual environment this will lead to different namespaces for each language 
          # (which may be intentional or not). Maybe one should make it configurable one day
 
          #    return $t_project_name . ':' . lang_get( 'bug' ) . ':' . $c_issue_id;   
 
	}
 
 	# ----------------------
	# Gets the page url for the specified issue id.
	function wiki_dokuwiki_get_url_for_issue( $p_issue_id ) {
		return wiki_dokuwiki_get_url_for_page_id( wiki_dokuwiki_get_page_id_for_issue( $p_issue_id ) );
	}
 
	# ----------------------
	# Gets the page id for the specified project.  The project id can be ALL_PROJECTS
	# The page id can then be converted to URL using wiki_dokuwiki_get_url_for_page_id().
	function wiki_dokuwiki_get_page_id_for_project( $p_project_id ) {
		$t_home = 'start';
		if ( $p_project_id == ALL_PROJECTS ) {
			return $t_home;
		} else {
			$t_project_name = project_get_name( $p_project_id );
			return $t_project_name . ':' . $t_home;
		}
	}
 
 	# ----------------------
	# Get URL for the specified project id.  The project is can be ALL_PROJECTS.
	function wiki_dokuwiki_get_url_for_project( $p_project_id ) {
		return wiki_dokuwiki_get_url_for_page_id( wiki_dokuwiki_get_page_id_for_project( $p_project_id ) );
	}
?>
 

html_api.php

Add the following with the rest of the includes:

require_once( $t_core_dir . 'wiki_api.php' );

In the print_menu() function, add the following code after the code which prints the Docs button (the block with the “Project Documentation Page” comment).

# Project Wiki
if ( wiki_is_enabled() ) {
	$t_current_project = helper_get_current_project();
	$t_menu_options[] = '<a href="wiki.php?type=project&id=' . $t_current_project . '">' . lang_get( 'wiki' ) . '</a>';
}

Add the following function:

# --------------------
# Print a button to create a wiki page
function html_button_wiki( $p_bug_id ) {
	if ( ON == config_get( 'wiki_enable' ) ) {
		if ( access_has_bug_level( config_get( 'update_bug_threshold' ), $p_bug_id ) ) {
			html_button( 'wiki.php',
						 lang_get_defaulted( 'Wiki' ),
						 array( 'id' => $p_bug_id, 'type' => 'issue' ),
						 'get' );
		}
	}
}

Update html_button() to the following implementation:

# --------------------
# Print an html button inside a form
function html_button ( $p_action, $p_button_text, $p_fields = null, $p_method = 'post' ) {
	$p_action		= urlencode( $p_action );
	$p_button_text	= string_attribute( $p_button_text );
	if ( null === $p_fields ) {
		$p_fields = array();
	}
	
	if ( strtolower( $p_method ) == 'get' ) {
		$t_method = 'get';
	} else {
		$t_method = 'post';
	}
 
	PRINT "<form method=\"$t_method\" action=\"$p_action\">\n";
 
	foreach ( $p_fields as $key => $val ) {
		$key = string_attribute( $key );
		$val = string_attribute( $val );
 
		PRINT "	<input type=\"hidden\" name=\"$key\" value=\"$val\" />\n";
	}
 
	PRINT "	<input type=\"submit\" class=\"button\" value=\"$p_button_text\" />\n";
	PRINT "</form>\n";
}

lang/strings_english.txt

Add the following at the end of the file but before the PHP end block (?>):

# wiki related strings
$s_wiki = 'Wiki';

wiki.php

Create wiki.php file in Mantis root folder:

<?php
	require_once( 'core.php' );
 
	$t_core_path = config_get( 'core_path' );
 
	require_once( $t_core_path . 'wiki_api.php' );
 
	$f_id = gpc_get_int( 'id' );
	$f_type = gpc_get_string( 'type', 'issue' );
	
	if ( $f_type == 'project' ) {
		project_ensure_exists( $f_id );
		$t_url = wiki_get_url_for_project( $f_id );
	} else {
		bug_ensure_exists( $f_id );
		$t_url = wiki_get_url_for_issue( $f_id );
	}
 
	print_header_redirect( $t_url );
?>
 

bug_view_*_page.php

Add the following code before the <td> tag that comes before the “<!– prev/next links –>” comment in both bug_view_page.php and bug_view_advanced_page.php.

<span class="small">
    <?php print_bracket_link( 'wiki.php?id='.$f_bug_id, lang_get( 'wiki' ) ) ?>
</span>

植物实例分割数据集 一、基础信息 数据集名称:植物实例分割数据集 图片数量: - 训练集:9,600张图片 - 验证集:913张图片 - 测试集:455张图片 总计:10,968张图片 分类类别:59个类别,对应数字标签0至58,涵盖多种植物状态或特征。 标注格式:YOLO格式,适用于实例分割任务,包含多边形标注点。 数据格式:图像文件,来源于植物图像数据库,适用于计算机视觉任务。 二、适用场景 • 农业植物监测AI系统开发:数据集支持实例分割任务,帮助构建能够自动识别植物特定区域并分类的AI模型,辅助农业专家进行精准监测和分析。 • 智能农业应用研发:集成至农业管理平台,提供实时植物状态识别功能,为作物健康管理和优化种植提供数据支持。 • 学术研究与农业创新:支持植物科学与人工智能交叉领域的研究,助力发表高水平农业AI论文。 • 农业教育与培训:数据集可用于农业院校或培训机构,作为学生学习植物图像分析和实例分割技术的重要资源。 三、数据集优势 • 精准标注与多样性:标注采用YOLO格式,确保分割区域定位精确;包含59个类别,覆盖多种植物状态,具有高度多样性。 • 数据量丰富:拥有超过10,000张图像,大规模数据支持模型充分学习和泛化。 • 任务适配性强:标注兼容主流深度学习框架(如YOLO、Mask R-CNN等),可直接用于实例分割任务,并可能扩展到目标检测或分类等任务。
以下是将 Android HAL(Hardware Abstraction Layer)与 TinyALSA 集成的实用指南: ### 理解 Android HAL 和 TinyALSA Android HAL 是一个抽象层,用于将 Android 系统与底层硬件隔离开来,使得上层软件可以以统一的接口访问不同的硬件设备。TinyALSA 是一个轻量级的 ALSA(Advanced Linux Sound Architecture)库,用于在 Linux 系统上进行音频设备的控制和音频数据的处理。 ### 准备工作 - **环境搭建**:确保开发环境中已经安装了 Android NDK、SDK 以及相关的编译工具链。 - **获取 TinyALSA 源码**:可以从 TinyALSA 的官方仓库或者开源代码托管平台获取其源码。 ### 集成步骤 #### 1. 配置 Android.mk 或 CMakeLists.txt 在 Android HAL 模块的 Android.mk 或者 CMakeLists.txt 文件中添加对 TinyALSA 库的依赖。 **Android.mk 示例**: ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := your_hal_module LOCAL_SRC_FILES := your_hal_source_files.c # 添加 TinyALSA 库的路径 LOCAL_C_INCLUDES += /path/to/tinyalsa/include # 链接 TinyALSA 库 LOCAL_SHARED_LIBRARIES := libtinyalsa include $(BUILD_SHARED_LIBRARY) ``` **CMakeLists.txt 示例**: ```cmake cmake_minimum_required(VERSION 3.4.1) add_library(your_hal_module SHARED your_hal_source_files.c) # 添加 TinyALSA 库的路径 include_directories(/path/to/tinyalsa/include) # 链接 TinyALSA 库 target_link_libraries(your_hal_module libtinyalsa) ``` #### 2. 包含 TinyALSA 头文件 在 Android HAL 模块的源代码文件中包含 TinyALSA 的头文件,以便使用其提供的 API。 ```c #include <tinyalsa/asoundlib.h> ``` #### 3. 使用 TinyALSA API 实现音频功能 在 Android HAL 模块中使用 TinyALSA 的 API 来实现音频设备的打开、关闭、音频数据的读写等功能。 **打开音频设备示例**: ```c #include <tinyalsa/asoundlib.h> struct pcm_config config; struct pcm *pcm; // 配置音频参数 config.channels = 2; config.rate = 44100; config.period_size = 1024; config.period_count = 4; config.format = PCM_FORMAT_S16_LE; config.start_threshold = 0; config.stop_threshold = 0; config.silence_threshold = 0; // 打开音频设备 pcm = pcm_open(0, 0, PCM_OUT, &config); if (!pcm || !pcm_is_ready(pcm)) { // 处理打开失败的情况 } ``` #### 4. 编译和测试 使用 Android NDK 或者 CMake 进行编译,将生成的库文件推送到 Android 设备上进行测试。 ### 注意事项 - **错误处理**:在使用 TinyALSA API 时,要注意对返回值进行检查,处理可能出现的错误情况。 - **资源管理**:在使用完音频设备后,要及时关闭设备,释放相关资源。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值