我在Ubuntu 16.04,GCC 5.4,最新的OpenCV。假设我有一个double的向量
import React, { Component } from 'react';
import { View, Text, FlatList, ActivityIndicator, Alert, TouchableOpacity} from "react-native";
import { List, ListItem, Icon } from "react-native-elements";
import { Navigator } from 'react-navigation';
import SearchBar from './SearchBar';
export default class Customer extends Component {
state = {
loading: false,
data: []
}
componentWillMount() {
this.searchCust('M000');
}
onPressSearch = term => {
if(term == '')
{
Alert.alert("Enter to search");
}
else
{
this.searchCust(term);
}
}
searchCust = term => {
this.setState({ loading: true });
const url = `http://xxx.xxx.xxx.xxx/app/customerlist.php?term=${term}`;
fetch(url)
.then(res => res.json())
.then(res => {
this.setState({
data: res.results,
error: res.error || null,
loading: false,
});
})
.catch(error => {
this.setState({ error });
});
}
goToCustomerDetail = (item) => {
this.props.navigation.navigate("CustomerDetail",{item}); //Alert.alert(item);//
}
render() {
const { loading, data } = this.state;
const { customers } = this.props;
return (
<View style={{ flex: 1, backgroundColor: '#fff' }}>
<SearchBar
loading={loading}
onPressSearch={this.onPressSearch}
/>
<List containerStyle={{ borderTopWidth: 0, borderBottomWidth: 0 }}>
<FlatList
data={data}
renderItem={({ item }) => {
const badge = {
value: `☆ ${item.custstar}`, {/* d is a database field*/}
badgeContainerStyle: { right: 10, backgroundColor: '#56579B' },
badgeTextStyle: { fontSize: 12 },
};
return (
<TouchableOpacity onPress={this.goToCustomerDetail.bind(this, item.custid)}>
<ListItem
style={{backgroundColor: 'transparent'}}
roundAvatar
title={`${item.custid}`}
subtitle={item.custname}
avatar={{ uri: item.imageurl }}
badge={badge}
containerStyle={{ borderBottomWidth: 1 }}
/>
</TouchableOpacity>
);
}
}
keyExtractor={item => item.custid}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
ListFooterComponent={this.renderFooter}
onRefresh={this.handleRefresh}
refreshing={this.state.refreshing}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={0.5}
/>
</List>
</View>
);
}
}
打印
std::vector<std::vector<double>> vecvecdouble;
vecvecdouble.resize(3, std::vector<double>(3, 0));
for (int j = 0; j < 3; j++){
for (int i = 0; i < 3; i++){
if (i == 0){
vecvecdouble[i][j] = 1;
vecvecdouble[i][j] = 1;
}
if (i == 1){
vecvecdouble[i][j] = 2;
vecvecdouble[i][j] = 2;
}
if (i == 1 && j == 0){
std::cout << vecvecdouble[i - 1][j] << std::endl;
std::cout << vecvecdouble[i][j] << std::endl;
std::cout << vecvecdouble[i + 1][j] << std::endl;
}
}
}
正如所料。但是,如果我使用OpenCV 1
2
0
cv::mat
打印
std::vector<std::vector<cv::Mat>> vecvecmat;
vecvecmat.resize(
3, std::vector<cv::Mat>(3, cv::Mat(4, 4, CV_64FC1, cv::Scalar(0.0))));
for (int j = 0; j < 3; j++){
for (int i = 0; i < 3; i++){
if (i == 0){
vecvecmat[i][j].at<double>(0, 0) = 1;
vecvecmat[i][j].at<double>(0, 1) = 1;
}
if (i == 1){
vecvecmat[i][j].at<double>(0, 0) = 2;
vecvecmat[i][j].at<double>(0, 1) = 2;
}
if (i == 1 && j == 0){
std::cout << vecvecmat[i - 1][j] << std::endl;
std::cout << vecvecmat[i][j] << std::endl;
std::cout << vecvecmat[i + 1][j] << std::endl;
}
}
}
这完全出乎意料,因为我期待它打印
[2, 2, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
[2, 2, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
[2, 2, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
但是,如果我不尝试在一行中调整向量的大小并经历两个for循环,它实际上会返回预期的结果
[1, 1, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
[2, 2, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
[0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
这条线有什么问题?
std::vector<std::vector<cv::Mat>> vecvecmat;
vecvecmat.resize(3);
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
cv::Mat mymat = cv::Mat(4, 4, CV_64FC1, cv::Scalar(0.0));
vecvecmat[i].push_back(mymat);
}
}
for (int j = 0; j < 3; j++){
for (int i = 0; i < 3; i++){
if (i == 0){
vecvecmat[i][j].at<double>(0, 0) = 1;
vecvecmat[i][j].at<double>(0, 1) = 1;
}
if (i == 1){
vecvecmat[i][j].at<double>(0, 0) = 2;
vecvecmat[i][j].at<double>(0, 1) = 2;
}
if (i == 1 && j == 0){
std::cout << vecvecmat[i - 1][j] << std::endl;
std::cout << vecvecmat[i][j] << std::endl;
std::cout << vecvecmat[i + 1][j] << std::endl;
}
}
}
答案 0 :(得分:2)
cv::Mat
says的复制构造函数的文档(强调我的):
参数
m
将(整体或部分)数组分配给构造的矩阵。 这些构造函数不会复制数据。而是构造指向m数据或其子数组的标头并将其与之关联。参考计数器(如果有)递增。因此,当您修改使用此类构造函数形成的矩阵时,还会修改m
的相应元素。如果您想拥有子阵列的独立副本,请使用Mat::clone()
。
您在调用std::vector::resize
时构造的初始矩阵正在使用此复制构造函数*复制到向量的每个元素中,因此它们都指向相同的数据。修改一个矩阵时,可以修改所有矩阵。
*或者可能与operator=
,它做同样的事情(我不确定哪一个,但它不影响结果)
我建议像这样初始化你的矢量:
std::vector<std::vector<cv::Mat>> vecvecmat;
vecvecmat.resize(3, std::vector<cv::Mat>());
for(auto& v : vecvecmat)
{
for(std::size_t i = 0; i < 3; ++i)
{
v.emplace_back(4, 4, CV_64FC1, cv::Scalar(0.0));
}
}